summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/gorilla
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2018-04-16 05:37:14 -0700
committerJoram Wilander <jwawilander@gmail.com>2018-04-16 08:37:14 -0400
commit6e2cb00008cbf09e556b00f87603797fcaa47e09 (patch)
tree3c0eb55ff4226a3f024aad373140d1fb860a6404 /vendor/github.com/gorilla
parentbf24f51c4e1cc6286885460672f7f449e8c6f5ef (diff)
downloadchat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.gz
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.bz2
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.zip
Depenancy upgrades and movign to dep. (#8630)
Diffstat (limited to 'vendor/github.com/gorilla')
-rw-r--r--vendor/github.com/gorilla/context/.travis.yml8
-rw-r--r--vendor/github.com/gorilla/context/README.md3
-rw-r--r--vendor/github.com/gorilla/context/context_test.go161
-rw-r--r--vendor/github.com/gorilla/context/doc.go6
-rw-r--r--vendor/github.com/gorilla/handlers/canonical_test.go127
-rw-r--r--vendor/github.com/gorilla/handlers/compress_test.go154
-rw-r--r--vendor/github.com/gorilla/handlers/cors_test.go371
-rw-r--r--vendor/github.com/gorilla/handlers/handlers_go18_test.go34
-rw-r--r--vendor/github.com/gorilla/handlers/handlers_test.go378
-rw-r--r--vendor/github.com/gorilla/handlers/proxy_headers_test.go111
-rw-r--r--vendor/github.com/gorilla/handlers/recovery_test.go44
-rw-r--r--vendor/github.com/gorilla/mux/bench_test.go49
-rw-r--r--vendor/github.com/gorilla/mux/context_gorilla_test.go40
-rw-r--r--vendor/github.com/gorilla/mux/context_native_test.go32
-rw-r--r--vendor/github.com/gorilla/mux/example_route_test.go51
-rw-r--r--vendor/github.com/gorilla/mux/middleware_test.go336
-rw-r--r--vendor/github.com/gorilla/mux/mux_test.go2347
-rw-r--r--vendor/github.com/gorilla/mux/old_test.go704
-rw-r--r--vendor/github.com/gorilla/schema/cache.go36
-rw-r--r--vendor/github.com/gorilla/schema/decoder.go89
-rw-r--r--vendor/github.com/gorilla/schema/decoder_test.go1693
-rw-r--r--vendor/github.com/gorilla/schema/encoder_test.go420
-rw-r--r--vendor/github.com/gorilla/websocket/.gitignore2
-rw-r--r--vendor/github.com/gorilla/websocket/.travis.yml11
-rw-r--r--vendor/github.com/gorilla/websocket/README.md2
-rw-r--r--vendor/github.com/gorilla/websocket/client.go12
-rw-r--r--vendor/github.com/gorilla/websocket/client_server_test.go602
-rw-r--r--vendor/github.com/gorilla/websocket/client_test.go32
-rw-r--r--vendor/github.com/gorilla/websocket/compression_test.go80
-rw-r--r--vendor/github.com/gorilla/websocket/conn.go17
-rw-r--r--vendor/github.com/gorilla/websocket/conn_broadcast_test.go134
-rw-r--r--vendor/github.com/gorilla/websocket/conn_test.go496
-rw-r--r--vendor/github.com/gorilla/websocket/conn_write.go15
-rw-r--r--vendor/github.com/gorilla/websocket/conn_write_legacy.go18
-rw-r--r--vendor/github.com/gorilla/websocket/example_test.go46
-rw-r--r--vendor/github.com/gorilla/websocket/examples/autobahn/README.md13
-rw-r--r--vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json15
-rw-r--r--vendor/github.com/gorilla/websocket/examples/autobahn/server.go265
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/README.md102
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/client.go137
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/home.html98
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/hub.go53
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/main.go40
-rw-r--r--vendor/github.com/gorilla/websocket/examples/command/README.md19
-rw-r--r--vendor/github.com/gorilla/websocket/examples/command/home.html102
-rw-r--r--vendor/github.com/gorilla/websocket/examples/command/main.go193
-rw-r--r--vendor/github.com/gorilla/websocket/examples/echo/README.md17
-rw-r--r--vendor/github.com/gorilla/websocket/examples/echo/client.go81
-rw-r--r--vendor/github.com/gorilla/websocket/examples/echo/server.go133
-rw-r--r--vendor/github.com/gorilla/websocket/examples/filewatch/README.md9
-rw-r--r--vendor/github.com/gorilla/websocket/examples/filewatch/main.go193
-rw-r--r--vendor/github.com/gorilla/websocket/json_test.go119
-rw-r--r--vendor/github.com/gorilla/websocket/mask_test.go73
-rw-r--r--vendor/github.com/gorilla/websocket/prepared_test.go74
-rw-r--r--vendor/github.com/gorilla/websocket/server.go2
-rw-r--r--vendor/github.com/gorilla/websocket/server_test.go69
-rw-r--r--vendor/github.com/gorilla/websocket/util_test.go95
57 files changed, 142 insertions, 10421 deletions
diff --git a/vendor/github.com/gorilla/context/.travis.yml b/vendor/github.com/gorilla/context/.travis.yml
index 6f440f1e4..faca4dad3 100644
--- a/vendor/github.com/gorilla/context/.travis.yml
+++ b/vendor/github.com/gorilla/context/.travis.yml
@@ -7,13 +7,13 @@ matrix:
- go: 1.4
- go: 1.5
- go: 1.6
- - go: 1.7
- - go: tip
- allow_failures:
- go: tip
+install:
+ - go get golang.org/x/tools/cmd/vet
+
script:
- go get -t -v ./...
- diff -u <(echo -n) <(gofmt -d .)
- - go vet $(go list ./... | grep -v /vendor/)
+ - go tool vet .
- go test -v -race ./...
diff --git a/vendor/github.com/gorilla/context/README.md b/vendor/github.com/gorilla/context/README.md
index 08f86693b..c60a31b05 100644
--- a/vendor/github.com/gorilla/context/README.md
+++ b/vendor/github.com/gorilla/context/README.md
@@ -4,7 +4,4 @@ context
gorilla/context is a general purpose registry for global request variables.
-> Note: gorilla/context, having been born well before `context.Context` existed, does not play well
-> with the shallow copying of the request that [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) (added to net/http Go 1.7 onwards) performs. You should either use *just* gorilla/context, or moving forward, the new `http.Request.Context()`.
-
Read the full documentation here: http://www.gorillatoolkit.org/pkg/context
diff --git a/vendor/github.com/gorilla/context/context_test.go b/vendor/github.com/gorilla/context/context_test.go
deleted file mode 100644
index d70e91a23..000000000
--- a/vendor/github.com/gorilla/context/context_test.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2012 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 context
-
-import (
- "net/http"
- "testing"
-)
-
-type keyType int
-
-const (
- key1 keyType = iota
- key2
-)
-
-func TestContext(t *testing.T) {
- assertEqual := func(val interface{}, exp interface{}) {
- if val != exp {
- t.Errorf("Expected %v, got %v.", exp, val)
- }
- }
-
- r, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
- emptyR, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
-
- // Get()
- assertEqual(Get(r, key1), nil)
-
- // Set()
- Set(r, key1, "1")
- assertEqual(Get(r, key1), "1")
- assertEqual(len(data[r]), 1)
-
- Set(r, key2, "2")
- assertEqual(Get(r, key2), "2")
- assertEqual(len(data[r]), 2)
-
- //GetOk
- value, ok := GetOk(r, key1)
- assertEqual(value, "1")
- assertEqual(ok, true)
-
- value, ok = GetOk(r, "not exists")
- assertEqual(value, nil)
- assertEqual(ok, false)
-
- Set(r, "nil value", nil)
- value, ok = GetOk(r, "nil value")
- assertEqual(value, nil)
- assertEqual(ok, true)
-
- // GetAll()
- values := GetAll(r)
- assertEqual(len(values), 3)
-
- // GetAll() for empty request
- values = GetAll(emptyR)
- if values != nil {
- t.Error("GetAll didn't return nil value for invalid request")
- }
-
- // GetAllOk()
- values, ok = GetAllOk(r)
- assertEqual(len(values), 3)
- assertEqual(ok, true)
-
- // GetAllOk() for empty request
- values, ok = GetAllOk(emptyR)
- assertEqual(len(values), 0)
- assertEqual(ok, false)
-
- // Delete()
- Delete(r, key1)
- assertEqual(Get(r, key1), nil)
- assertEqual(len(data[r]), 2)
-
- Delete(r, key2)
- assertEqual(Get(r, key2), nil)
- assertEqual(len(data[r]), 1)
-
- // Clear()
- Clear(r)
- assertEqual(len(data), 0)
-}
-
-func parallelReader(r *http.Request, key string, iterations int, wait, done chan struct{}) {
- <-wait
- for i := 0; i < iterations; i++ {
- Get(r, key)
- }
- done <- struct{}{}
-
-}
-
-func parallelWriter(r *http.Request, key, value string, iterations int, wait, done chan struct{}) {
- <-wait
- for i := 0; i < iterations; i++ {
- Set(r, key, value)
- }
- done <- struct{}{}
-
-}
-
-func benchmarkMutex(b *testing.B, numReaders, numWriters, iterations int) {
-
- b.StopTimer()
- r, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
- done := make(chan struct{})
- b.StartTimer()
-
- for i := 0; i < b.N; i++ {
- wait := make(chan struct{})
-
- for i := 0; i < numReaders; i++ {
- go parallelReader(r, "test", iterations, wait, done)
- }
-
- for i := 0; i < numWriters; i++ {
- go parallelWriter(r, "test", "123", iterations, wait, done)
- }
-
- close(wait)
-
- for i := 0; i < numReaders+numWriters; i++ {
- <-done
- }
-
- }
-
-}
-
-func BenchmarkMutexSameReadWrite1(b *testing.B) {
- benchmarkMutex(b, 1, 1, 32)
-}
-func BenchmarkMutexSameReadWrite2(b *testing.B) {
- benchmarkMutex(b, 2, 2, 32)
-}
-func BenchmarkMutexSameReadWrite4(b *testing.B) {
- benchmarkMutex(b, 4, 4, 32)
-}
-func BenchmarkMutex1(b *testing.B) {
- benchmarkMutex(b, 2, 8, 32)
-}
-func BenchmarkMutex2(b *testing.B) {
- benchmarkMutex(b, 16, 4, 64)
-}
-func BenchmarkMutex3(b *testing.B) {
- benchmarkMutex(b, 1, 2, 128)
-}
-func BenchmarkMutex4(b *testing.B) {
- benchmarkMutex(b, 128, 32, 256)
-}
-func BenchmarkMutex5(b *testing.B) {
- benchmarkMutex(b, 1024, 2048, 64)
-}
-func BenchmarkMutex6(b *testing.B) {
- benchmarkMutex(b, 2048, 1024, 512)
-}
diff --git a/vendor/github.com/gorilla/context/doc.go b/vendor/github.com/gorilla/context/doc.go
index 448d1bfca..73c740031 100644
--- a/vendor/github.com/gorilla/context/doc.go
+++ b/vendor/github.com/gorilla/context/doc.go
@@ -5,12 +5,6 @@
/*
Package context stores values shared during a request lifetime.
-Note: gorilla/context, having been born well before `context.Context` existed,
-does not play well > with the shallow copying of the request that
-[`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext)
-(added to net/http Go 1.7 onwards) performs. You should either use *just*
-gorilla/context, or moving forward, the new `http.Request.Context()`.
-
For example, a router can set variables extracted from the URL and later
application handlers can access those values, or it can be used to store
sessions values to be saved at the end of a request. There are several
diff --git a/vendor/github.com/gorilla/handlers/canonical_test.go b/vendor/github.com/gorilla/handlers/canonical_test.go
deleted file mode 100644
index 615e4b056..000000000
--- a/vendor/github.com/gorilla/handlers/canonical_test.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package handlers
-
-import (
- "bufio"
- "bytes"
- "log"
- "net/http"
- "net/http/httptest"
- "net/url"
- "strings"
- "testing"
-)
-
-func TestCleanHost(t *testing.T) {
- tests := []struct {
- in, want string
- }{
- {"www.google.com", "www.google.com"},
- {"www.google.com foo", "www.google.com"},
- {"www.google.com/foo", "www.google.com"},
- {" first character is a space", ""},
- }
- for _, tt := range tests {
- got := cleanHost(tt.in)
- if tt.want != got {
- t.Errorf("cleanHost(%q) = %q, want %q", tt.in, got, tt.want)
- }
- }
-}
-
-func TestCanonicalHost(t *testing.T) {
- gorilla := "http://www.gorillatoolkit.org"
-
- rr := httptest.NewRecorder()
- r := newRequest("GET", "http://www.example.com/")
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- // Test a re-direct: should return a 302 Found.
- CanonicalHost(gorilla, http.StatusFound)(testHandler).ServeHTTP(rr, r)
-
- if rr.Code != http.StatusFound {
- t.Fatalf("bad status: got %v want %v", rr.Code, http.StatusFound)
- }
-
- if rr.Header().Get("Location") != gorilla+r.URL.Path {
- t.Fatalf("bad re-direct: got %q want %q", rr.Header().Get("Location"), gorilla+r.URL.Path)
- }
-
-}
-
-func TestKeepsQueryString(t *testing.T) {
- google := "https://www.google.com"
-
- rr := httptest.NewRecorder()
- querystring := url.Values{"q": {"golang"}, "format": {"json"}}.Encode()
- r := newRequest("GET", "http://www.example.com/search?"+querystring)
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
- CanonicalHost(google, http.StatusFound)(testHandler).ServeHTTP(rr, r)
-
- want := google + r.URL.Path + "?" + querystring
- if rr.Header().Get("Location") != want {
- t.Fatalf("bad re-direct: got %q want %q", rr.Header().Get("Location"), want)
- }
-}
-
-func TestBadDomain(t *testing.T) {
- rr := httptest.NewRecorder()
- r := newRequest("GET", "http://www.example.com/")
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- // Test a bad domain - should return 200 OK.
- CanonicalHost("%", http.StatusFound)(testHandler).ServeHTTP(rr, r)
-
- if rr.Code != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", rr.Code, http.StatusOK)
- }
-}
-
-func TestEmptyHost(t *testing.T) {
- rr := httptest.NewRecorder()
- r := newRequest("GET", "http://www.example.com/")
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- // Test a domain that returns an empty url.Host from url.Parse.
- CanonicalHost("hello.com", http.StatusFound)(testHandler).ServeHTTP(rr, r)
-
- if rr.Code != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", rr.Code, http.StatusOK)
- }
-}
-
-func TestHeaderWrites(t *testing.T) {
- gorilla := "http://www.gorillatoolkit.org"
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(200)
- })
-
- // Catch the log output to ensure we don't write multiple headers.
- var b bytes.Buffer
- buf := bufio.NewWriter(&b)
- tl := log.New(buf, "test: ", log.Lshortfile)
-
- srv := httptest.NewServer(
- CanonicalHost(gorilla, http.StatusFound)(testHandler))
- defer srv.Close()
- srv.Config.ErrorLog = tl
-
- _, err := http.Get(srv.URL)
- if err != nil {
- t.Fatal(err)
- }
-
- err = buf.Flush()
- if err != nil {
- t.Fatal(err)
- }
-
- // We rely on the error not changing: net/http does not export it.
- if strings.Contains(b.String(), "multiple response.WriteHeader calls") {
- t.Fatalf("re-direct did not return early: multiple header writes")
- }
-}
diff --git a/vendor/github.com/gorilla/handlers/compress_test.go b/vendor/github.com/gorilla/handlers/compress_test.go
deleted file mode 100644
index 6f07f440d..000000000
--- a/vendor/github.com/gorilla/handlers/compress_test.go
+++ /dev/null
@@ -1,154 +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"
- "io"
- "net"
- "net/http"
- "net/http/httptest"
- "strconv"
- "testing"
-)
-
-var contentType = "text/plain; charset=utf-8"
-
-func compressedRequest(w *httptest.ResponseRecorder, compression string) {
- CompressHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Length", strconv.Itoa(9*1024))
- w.Header().Set("Content-Type", contentType)
- for i := 0; i < 1024; i++ {
- io.WriteString(w, "Gorilla!\n")
- }
- })).ServeHTTP(w, &http.Request{
- Method: "GET",
- Header: http.Header{
- "Accept-Encoding": []string{compression},
- },
- })
-
-}
-
-func TestCompressHandlerNoCompression(t *testing.T) {
- w := httptest.NewRecorder()
- compressedRequest(w, "")
- if enc := w.HeaderMap.Get("Content-Encoding"); enc != "" {
- t.Errorf("wrong content encoding, got %q want %q", enc, "")
- }
- if ct := w.HeaderMap.Get("Content-Type"); ct != contentType {
- t.Errorf("wrong content type, got %q want %q", ct, contentType)
- }
- if w.Body.Len() != 1024*9 {
- t.Errorf("wrong len, got %d want %d", w.Body.Len(), 1024*9)
- }
- if l := w.HeaderMap.Get("Content-Length"); l != "9216" {
- t.Errorf("wrong content-length. got %q expected %d", l, 1024*9)
- }
-}
-
-func TestCompressHandlerGzip(t *testing.T) {
- w := httptest.NewRecorder()
- compressedRequest(w, "gzip")
- if w.HeaderMap.Get("Content-Encoding") != "gzip" {
- t.Errorf("wrong content encoding, got %q want %q", w.HeaderMap.Get("Content-Encoding"), "gzip")
- }
- if w.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
- t.Errorf("wrong content type, got %s want %s", w.HeaderMap.Get("Content-Type"), "text/plain; charset=utf-8")
- }
- if w.Body.Len() != 72 {
- t.Errorf("wrong len, got %d want %d", w.Body.Len(), 72)
- }
- if l := w.HeaderMap.Get("Content-Length"); l != "" {
- t.Errorf("wrong content-length. got %q expected %q", l, "")
- }
-}
-
-func TestCompressHandlerDeflate(t *testing.T) {
- w := httptest.NewRecorder()
- compressedRequest(w, "deflate")
- if w.HeaderMap.Get("Content-Encoding") != "deflate" {
- t.Fatalf("wrong content encoding, got %q want %q", w.HeaderMap.Get("Content-Encoding"), "deflate")
- }
- if w.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
- t.Fatalf("wrong content type, got %s want %s", w.HeaderMap.Get("Content-Type"), "text/plain; charset=utf-8")
- }
- if w.Body.Len() != 54 {
- t.Fatalf("wrong len, got %d want %d", w.Body.Len(), 54)
- }
-}
-
-func TestCompressHandlerGzipDeflate(t *testing.T) {
- w := httptest.NewRecorder()
- compressedRequest(w, "gzip, deflate ")
- if w.HeaderMap.Get("Content-Encoding") != "gzip" {
- t.Fatalf("wrong content encoding, got %q want %q", w.HeaderMap.Get("Content-Encoding"), "gzip")
- }
- if w.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
- t.Fatalf("wrong content type, got %s want %s", w.HeaderMap.Get("Content-Type"), "text/plain; charset=utf-8")
- }
-}
-
-type fullyFeaturedResponseWriter struct{}
-
-// Header/Write/WriteHeader implement the http.ResponseWriter interface.
-func (fullyFeaturedResponseWriter) Header() http.Header {
- return http.Header{}
-}
-func (fullyFeaturedResponseWriter) Write([]byte) (int, error) {
- return 0, nil
-}
-func (fullyFeaturedResponseWriter) WriteHeader(int) {}
-
-// Flush implements the http.Flusher interface.
-func (fullyFeaturedResponseWriter) Flush() {}
-
-// Hijack implements the http.Hijacker interface.
-func (fullyFeaturedResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- return nil, nil, nil
-}
-
-// CloseNotify implements the http.CloseNotifier interface.
-func (fullyFeaturedResponseWriter) CloseNotify() <-chan bool {
- return nil
-}
-
-func TestCompressHandlerPreserveInterfaces(t *testing.T) {
- // Compile time validation fullyFeaturedResponseWriter implements all the
- // interfaces we're asserting in the test case below.
- var (
- _ http.Flusher = fullyFeaturedResponseWriter{}
- _ http.CloseNotifier = fullyFeaturedResponseWriter{}
- _ http.Hijacker = fullyFeaturedResponseWriter{}
- )
- var h http.Handler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
- comp := r.Header.Get("Accept-Encoding")
- if _, ok := rw.(*compressResponseWriter); !ok {
- t.Fatalf("ResponseWriter wasn't wrapped by compressResponseWriter, got %T type", rw)
- }
- if _, ok := rw.(http.Flusher); !ok {
- t.Errorf("ResponseWriter lost http.Flusher interface for %q", comp)
- }
- if _, ok := rw.(http.CloseNotifier); !ok {
- t.Errorf("ResponseWriter lost http.CloseNotifier interface for %q", comp)
- }
- if _, ok := rw.(http.Hijacker); !ok {
- t.Errorf("ResponseWriter lost http.Hijacker interface for %q", comp)
- }
- })
- h = CompressHandler(h)
- var (
- rw fullyFeaturedResponseWriter
- )
- r, err := http.NewRequest("GET", "/", nil)
- if err != nil {
- t.Fatalf("Failed to create test request: %v", err)
- }
- r.Header.Set("Accept-Encoding", "gzip")
- h.ServeHTTP(rw, r)
-
- r.Header.Set("Accept-Encoding", "deflate")
- h.ServeHTTP(rw, r)
-}
diff --git a/vendor/github.com/gorilla/handlers/cors_test.go b/vendor/github.com/gorilla/handlers/cors_test.go
deleted file mode 100644
index 61eb18f77..000000000
--- a/vendor/github.com/gorilla/handlers/cors_test.go
+++ /dev/null
@@ -1,371 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
-)
-
-func TestDefaultCORSHandlerReturnsOk(t *testing.T) {
- r := newRequest("GET", "http://www.example.com/")
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS()(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusFound)
- }
-}
-
-func TestDefaultCORSHandlerReturnsOkWithOrigin(t *testing.T) {
- r := newRequest("GET", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS()(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusFound)
- }
-}
-
-func TestCORSHandlerIgnoreOptionsFallsThrough(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusTeapot)
- })
-
- CORS(IgnoreOptions())(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusTeapot {
- t.Fatalf("bad status: got %v want %v", status, http.StatusTeapot)
- }
-}
-
-func TestCORSHandlerSetsExposedHeaders(t *testing.T) {
- // Test default configuration.
- r := newRequest("GET", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS(ExposedHeaders([]string{"X-CORS-TEST"}))(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsExposeHeadersHeader)
- if header != "X-Cors-Test" {
- t.Fatal("bad header: expected X-Cors-Test header, got empty header for method.")
- }
-}
-
-func TestCORSHandlerUnsetRequestMethodForPreflightBadRequest(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS(AllowedMethods([]string{"DELETE"}))(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusBadRequest {
- t.Fatalf("bad status: got %v want %v", status, http.StatusBadRequest)
- }
-}
-
-func TestCORSHandlerInvalidRequestMethodForPreflightMethodNotAllowed(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, "DELETE")
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS()(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusMethodNotAllowed {
- t.Fatalf("bad status: got %v want %v", status, http.StatusMethodNotAllowed)
- }
-}
-
-func TestCORSHandlerOptionsRequestMustNotBePassedToNextHandler(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, "GET")
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("Options request must not be passed to next handler")
- })
-
- CORS()(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-}
-
-func TestCORSHandlerAllowedMethodForPreflight(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, "DELETE")
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS(AllowedMethods([]string{"DELETE"}))(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsAllowMethodsHeader)
- if header != "DELETE" {
- t.Fatalf("bad header: expected DELETE method header, got empty header.")
- }
-}
-
-func TestCORSHandlerAllowMethodsNotSetForSimpleRequestPreflight(t *testing.T) {
- for _, method := range defaultCorsMethods {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, method)
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS()(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsAllowMethodsHeader)
- if header != "" {
- t.Fatalf("bad header: expected empty method header, got %s.", header)
- }
- }
-}
-
-func TestCORSHandlerAllowedHeaderNotSetForSimpleRequestPreflight(t *testing.T) {
- for _, simpleHeader := range defaultCorsHeaders {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, "GET")
- r.Header.Set(corsRequestHeadersHeader, simpleHeader)
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS()(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsAllowHeadersHeader)
- if header != "" {
- t.Fatalf("bad header: expected empty header, got %s.", header)
- }
- }
-}
-
-func TestCORSHandlerAllowedHeaderForPreflight(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, "POST")
- r.Header.Set(corsRequestHeadersHeader, "Content-Type")
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS(AllowedHeaders([]string{"Content-Type"}))(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsAllowHeadersHeader)
- if header != "Content-Type" {
- t.Fatalf("bad header: expected Content-Type header, got empty header.")
- }
-}
-
-func TestCORSHandlerInvalidHeaderForPreflightForbidden(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, "POST")
- r.Header.Set(corsRequestHeadersHeader, "Content-Type")
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS()(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusForbidden {
- t.Fatalf("bad status: got %v want %v", status, http.StatusForbidden)
- }
-}
-
-func TestCORSHandlerMaxAgeForPreflight(t *testing.T) {
- r := newRequest("OPTIONS", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
- r.Header.Set(corsRequestMethodHeader, "POST")
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS(MaxAge(3500))(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsMaxAgeHeader)
- if header != "600" {
- t.Fatalf("bad header: expected %s to be %s, got %s.", corsMaxAgeHeader, "600", header)
- }
-}
-
-func TestCORSHandlerAllowedCredentials(t *testing.T) {
- r := newRequest("GET", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS(AllowCredentials())(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsAllowCredentialsHeader)
- if header != "true" {
- t.Fatalf("bad header: expected %s to be %s, got %s.", corsAllowCredentialsHeader, "true", header)
- }
-}
-
-func TestCORSHandlerMultipleAllowOriginsSetsVaryHeader(t *testing.T) {
- r := newRequest("GET", "http://www.example.com/")
- r.Header.Set("Origin", r.URL.String())
-
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- CORS(AllowedOrigins([]string{r.URL.String(), "http://google.com"}))(testHandler).ServeHTTP(rr, r)
-
- if status := rr.Code; status != http.StatusOK {
- t.Fatalf("bad status: got %v want %v", status, http.StatusOK)
- }
-
- header := rr.HeaderMap.Get(corsVaryHeader)
- if header != corsOriginHeader {
- t.Fatalf("bad header: expected %s to be %s, got %s.", corsVaryHeader, corsOriginHeader, header)
- }
-}
-
-func TestCORSWithMultipleHandlers(t *testing.T) {
- var lastHandledBy string
- corsMiddleware := CORS()
-
- testHandler1 := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- lastHandledBy = "testHandler1"
- })
- testHandler2 := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- lastHandledBy = "testHandler2"
- })
-
- r1 := newRequest("GET", "http://www.example.com/")
- rr1 := httptest.NewRecorder()
- handler1 := corsMiddleware(testHandler1)
-
- corsMiddleware(testHandler2)
-
- handler1.ServeHTTP(rr1, r1)
- if lastHandledBy != "testHandler1" {
- t.Fatalf("bad CORS() registration: Handler served should be Handler registered")
- }
-}
-
-func TestCORSHandlerWithCustomValidator(t *testing.T) {
- r := newRequest("GET", "http://a.example.com")
- r.Header.Set("Origin", r.URL.String())
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
-
- originValidator := func(origin string) bool {
- if strings.HasSuffix(origin, ".example.com") {
- return true
- }
- return false
- }
-
- // Specially craft a CORS object.
- handleFunc := func(h http.Handler) http.Handler {
- c := &cors{
- allowedMethods: defaultCorsMethods,
- allowedHeaders: defaultCorsHeaders,
- allowedOrigins: []string{"http://a.example.com"},
- h: h,
- }
- AllowedOriginValidator(originValidator)(c)
- return c
- }
-
- handleFunc(testHandler).ServeHTTP(rr, r)
- header := rr.HeaderMap.Get(corsAllowOriginHeader)
- if header != r.URL.String() {
- t.Fatalf("bad header: expected %s to be %s, got %s.", corsAllowOriginHeader, r.URL.String(), header)
- }
-
-}
-
-func TestCORSAllowStar(t *testing.T) {
- r := newRequest("GET", "http://a.example.com")
- r.Header.Set("Origin", r.URL.String())
- rr := httptest.NewRecorder()
-
- testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
- originValidator := func(origin string) bool {
- if strings.HasSuffix(origin, ".example.com") {
- return true
- }
- return false
- }
-
- CORS(AllowedOriginValidator(originValidator))(testHandler).ServeHTTP(rr, r)
- header := rr.HeaderMap.Get(corsAllowOriginHeader)
- // Because * is the default CORS policy (which is safe), we should be
- // expect a * returned here as the Access Control Allow Origin header
- if header != "*" {
- t.Fatalf("bad header: expected %s to be %s, got %s.", corsAllowOriginHeader, r.URL.String(), header)
- }
-
-}
diff --git a/vendor/github.com/gorilla/handlers/handlers_go18_test.go b/vendor/github.com/gorilla/handlers/handlers_go18_test.go
deleted file mode 100644
index c8cfa722f..000000000
--- a/vendor/github.com/gorilla/handlers/handlers_go18_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// +build go1.8
-
-package handlers
-
-import (
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-func TestLoggingHandlerWithPush(t *testing.T) {
- handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- if _, ok := w.(http.Pusher); !ok {
- t.Fatalf("%T from LoggingHandler does not satisfy http.Pusher interface when built with Go >=1.8", w)
- }
- w.WriteHeader(200)
- })
-
- logger := LoggingHandler(ioutil.Discard, handler)
- logger.ServeHTTP(httptest.NewRecorder(), newRequest("GET", "/"))
-}
-
-func TestCombinedLoggingHandlerWithPush(t *testing.T) {
- handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- if _, ok := w.(http.Pusher); !ok {
- t.Fatalf("%T from CombinedLoggingHandler does not satisfy http.Pusher interface when built with Go >=1.8", w)
- }
- w.WriteHeader(200)
- })
-
- logger := CombinedLoggingHandler(ioutil.Discard, handler)
- logger.ServeHTTP(httptest.NewRecorder(), newRequest("GET", "/"))
-}
diff --git a/vendor/github.com/gorilla/handlers/handlers_test.go b/vendor/github.com/gorilla/handlers/handlers_test.go
deleted file mode 100644
index 04ee24497..000000000
--- a/vendor/github.com/gorilla/handlers/handlers_test.go
+++ /dev/null
@@ -1,378 +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 (
- "bytes"
- "net"
- "net/http"
- "net/http/httptest"
- "net/url"
- "strings"
- "testing"
- "time"
-)
-
-const (
- ok = "ok\n"
- notAllowed = "Method not allowed\n"
-)
-
-var okHandler = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- w.Write([]byte(ok))
-})
-
-func newRequest(method, url string) *http.Request {
- req, err := http.NewRequest(method, url, nil)
- if err != nil {
- panic(err)
- }
- return req
-}
-
-func TestMethodHandler(t *testing.T) {
- tests := []struct {
- req *http.Request
- handler http.Handler
- code int
- allow string // Contents of the Allow header
- body string
- }{
- // No handlers
- {newRequest("GET", "/foo"), MethodHandler{}, http.StatusMethodNotAllowed, "", notAllowed},
- {newRequest("OPTIONS", "/foo"), MethodHandler{}, http.StatusOK, "", ""},
-
- // A single handler
- {newRequest("GET", "/foo"), MethodHandler{"GET": okHandler}, http.StatusOK, "", ok},
- {newRequest("POST", "/foo"), MethodHandler{"GET": okHandler}, http.StatusMethodNotAllowed, "GET", notAllowed},
-
- // Multiple handlers
- {newRequest("GET", "/foo"), MethodHandler{"GET": okHandler, "POST": okHandler}, http.StatusOK, "", ok},
- {newRequest("POST", "/foo"), MethodHandler{"GET": okHandler, "POST": okHandler}, http.StatusOK, "", ok},
- {newRequest("DELETE", "/foo"), MethodHandler{"GET": okHandler, "POST": okHandler}, http.StatusMethodNotAllowed, "GET, POST", notAllowed},
- {newRequest("OPTIONS", "/foo"), MethodHandler{"GET": okHandler, "POST": okHandler}, http.StatusOK, "GET, POST", ""},
-
- // Override OPTIONS
- {newRequest("OPTIONS", "/foo"), MethodHandler{"OPTIONS": okHandler}, http.StatusOK, "", ok},
- }
-
- for i, test := range tests {
- rec := httptest.NewRecorder()
- test.handler.ServeHTTP(rec, test.req)
- if rec.Code != test.code {
- t.Fatalf("%d: wrong code, got %d want %d", i, rec.Code, test.code)
- }
- if allow := rec.HeaderMap.Get("Allow"); allow != test.allow {
- t.Fatalf("%d: wrong Allow, got %s want %s", i, allow, test.allow)
- }
- if body := rec.Body.String(); body != test.body {
- t.Fatalf("%d: wrong body, got %q want %q", i, body, test.body)
- }
- }
-}
-
-func TestMakeLogger(t *testing.T) {
- rec := httptest.NewRecorder()
- logger := makeLogger(rec)
- // initial status
- if logger.Status() != http.StatusOK {
- t.Fatalf("wrong status, got %d want %d", logger.Status(), http.StatusOK)
- }
- // WriteHeader
- logger.WriteHeader(http.StatusInternalServerError)
- if logger.Status() != http.StatusInternalServerError {
- t.Fatalf("wrong status, got %d want %d", logger.Status(), http.StatusInternalServerError)
- }
- // Write
- logger.Write([]byte(ok))
- if logger.Size() != len(ok) {
- t.Fatalf("wrong size, got %d want %d", logger.Size(), len(ok))
- }
- // Header
- logger.Header().Set("key", "value")
- if val := logger.Header().Get("key"); val != "value" {
- t.Fatalf("wrong header, got %s want %s", val, "value")
- }
-}
-
-func TestWriteLog(t *testing.T) {
- loc, err := time.LoadLocation("Europe/Warsaw")
- if err != nil {
- panic(err)
- }
- ts := time.Date(1983, 05, 26, 3, 30, 45, 0, loc)
-
- // A typical request with an OK response
- req := newRequest("GET", "http://example.com")
- req.RemoteAddr = "192.168.100.5"
-
- buf := new(bytes.Buffer)
- writeLog(buf, req, *req.URL, ts, http.StatusOK, 100)
- log := buf.String()
-
- expected := "192.168.100.5 - - [26/May/1983:03:30:45 +0200] \"GET / HTTP/1.1\" 200 100\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-
- // CONNECT request over http/2.0
- req = &http.Request{
- Method: "CONNECT",
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- ProtoMinor: 0,
- URL: &url.URL{Host: "www.example.com:443"},
- Host: "www.example.com:443",
- RemoteAddr: "192.168.100.5",
- }
-
- buf = new(bytes.Buffer)
- writeLog(buf, req, *req.URL, ts, http.StatusOK, 100)
- log = buf.String()
-
- expected = "192.168.100.5 - - [26/May/1983:03:30:45 +0200] \"CONNECT www.example.com:443 HTTP/2.0\" 200 100\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-
- // Request with an unauthorized user
- req = newRequest("GET", "http://example.com")
- req.RemoteAddr = "192.168.100.5"
- req.URL.User = url.User("kamil")
-
- buf.Reset()
- writeLog(buf, req, *req.URL, ts, http.StatusUnauthorized, 500)
- log = buf.String()
-
- expected = "192.168.100.5 - kamil [26/May/1983:03:30:45 +0200] \"GET / HTTP/1.1\" 401 500\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-
- // Request with url encoded parameters
- req = newRequest("GET", "http://example.com/test?abc=hello%20world&a=b%3F")
- req.RemoteAddr = "192.168.100.5"
-
- buf.Reset()
- writeLog(buf, req, *req.URL, ts, http.StatusOK, 100)
- log = buf.String()
-
- expected = "192.168.100.5 - - [26/May/1983:03:30:45 +0200] \"GET /test?abc=hello%20world&a=b%3F HTTP/1.1\" 200 100\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-}
-
-func TestWriteCombinedLog(t *testing.T) {
- loc, err := time.LoadLocation("Europe/Warsaw")
- if err != nil {
- panic(err)
- }
- ts := time.Date(1983, 05, 26, 3, 30, 45, 0, loc)
-
- // A typical request with an OK response
- req := newRequest("GET", "http://example.com")
- req.RemoteAddr = "192.168.100.5"
- req.Header.Set("Referer", "http://example.com")
- req.Header.Set(
- "User-Agent",
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.33 "+
- "(KHTML, like Gecko) Chrome/27.0.1430.0 Safari/537.33",
- )
-
- buf := new(bytes.Buffer)
- writeCombinedLog(buf, req, *req.URL, ts, http.StatusOK, 100)
- log := buf.String()
-
- expected := "192.168.100.5 - - [26/May/1983:03:30:45 +0200] \"GET / HTTP/1.1\" 200 100 \"http://example.com\" " +
- "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) " +
- "AppleWebKit/537.33 (KHTML, like Gecko) Chrome/27.0.1430.0 Safari/537.33\"\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-
- // CONNECT request over http/2.0
- req1 := &http.Request{
- Method: "CONNECT",
- Host: "www.example.com:443",
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- ProtoMinor: 0,
- RemoteAddr: "192.168.100.5",
- Header: http.Header{},
- URL: &url.URL{Host: "www.example.com:443"},
- }
- req1.Header.Set("Referer", "http://example.com")
- req1.Header.Set(
- "User-Agent",
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.33 "+
- "(KHTML, like Gecko) Chrome/27.0.1430.0 Safari/537.33",
- )
-
- buf = new(bytes.Buffer)
- writeCombinedLog(buf, req1, *req1.URL, ts, http.StatusOK, 100)
- log = buf.String()
-
- expected = "192.168.100.5 - - [26/May/1983:03:30:45 +0200] \"CONNECT www.example.com:443 HTTP/2.0\" 200 100 \"http://example.com\" " +
- "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) " +
- "AppleWebKit/537.33 (KHTML, like Gecko) Chrome/27.0.1430.0 Safari/537.33\"\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-
- // Request with an unauthorized user
- req.URL.User = url.User("kamil")
-
- buf.Reset()
- writeCombinedLog(buf, req, *req.URL, ts, http.StatusUnauthorized, 500)
- log = buf.String()
-
- expected = "192.168.100.5 - kamil [26/May/1983:03:30:45 +0200] \"GET / HTTP/1.1\" 401 500 \"http://example.com\" " +
- "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) " +
- "AppleWebKit/537.33 (KHTML, like Gecko) Chrome/27.0.1430.0 Safari/537.33\"\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-
- // Test with remote ipv6 address
- req.RemoteAddr = "::1"
-
- buf.Reset()
- writeCombinedLog(buf, req, *req.URL, ts, http.StatusOK, 100)
- log = buf.String()
-
- expected = "::1 - kamil [26/May/1983:03:30:45 +0200] \"GET / HTTP/1.1\" 200 100 \"http://example.com\" " +
- "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) " +
- "AppleWebKit/537.33 (KHTML, like Gecko) Chrome/27.0.1430.0 Safari/537.33\"\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-
- // Test remote ipv6 addr, with port
- req.RemoteAddr = net.JoinHostPort("::1", "65000")
-
- buf.Reset()
- writeCombinedLog(buf, req, *req.URL, ts, http.StatusOK, 100)
- log = buf.String()
-
- expected = "::1 - kamil [26/May/1983:03:30:45 +0200] \"GET / HTTP/1.1\" 200 100 \"http://example.com\" " +
- "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) " +
- "AppleWebKit/537.33 (KHTML, like Gecko) Chrome/27.0.1430.0 Safari/537.33\"\n"
- if log != expected {
- t.Fatalf("wrong log, got %q want %q", log, expected)
- }
-}
-
-func TestLogPathRewrites(t *testing.T) {
- var buf bytes.Buffer
-
- handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- req.URL.Path = "/" // simulate http.StripPrefix and friends
- w.WriteHeader(200)
- })
- logger := LoggingHandler(&buf, handler)
-
- logger.ServeHTTP(httptest.NewRecorder(), newRequest("GET", "/subdir/asdf"))
-
- if !strings.Contains(buf.String(), "GET /subdir/asdf HTTP") {
- t.Fatalf("Got log %#v, wanted substring %#v", buf.String(), "GET /subdir/asdf HTTP")
- }
-}
-
-func BenchmarkWriteLog(b *testing.B) {
- loc, err := time.LoadLocation("Europe/Warsaw")
- if err != nil {
- b.Fatalf(err.Error())
- }
- ts := time.Date(1983, 05, 26, 3, 30, 45, 0, loc)
-
- req := newRequest("GET", "http://example.com")
- req.RemoteAddr = "192.168.100.5"
-
- b.ResetTimer()
-
- buf := &bytes.Buffer{}
- for i := 0; i < b.N; i++ {
- buf.Reset()
- writeLog(buf, req, *req.URL, ts, http.StatusUnauthorized, 500)
- }
-}
-
-func TestContentTypeHandler(t *testing.T) {
- tests := []struct {
- Method string
- AllowContentTypes []string
- ContentType string
- Code int
- }{
- {"POST", []string{"application/json"}, "application/json", http.StatusOK},
- {"POST", []string{"application/json", "application/xml"}, "application/json", http.StatusOK},
- {"POST", []string{"application/json"}, "application/json; charset=utf-8", http.StatusOK},
- {"POST", []string{"application/json"}, "application/json+xxx", http.StatusUnsupportedMediaType},
- {"POST", []string{"application/json"}, "text/plain", http.StatusUnsupportedMediaType},
- {"GET", []string{"application/json"}, "", http.StatusOK},
- {"GET", []string{}, "", http.StatusOK},
- }
- for _, test := range tests {
- r, err := http.NewRequest(test.Method, "/", nil)
- if err != nil {
- t.Error(err)
- continue
- }
-
- h := ContentTypeHandler(okHandler, test.AllowContentTypes...)
- r.Header.Set("Content-Type", test.ContentType)
- w := httptest.NewRecorder()
- h.ServeHTTP(w, r)
- if w.Code != test.Code {
- t.Errorf("expected %d, got %d", test.Code, w.Code)
- }
- }
-}
-
-func TestHTTPMethodOverride(t *testing.T) {
- var tests = []struct {
- Method string
- OverrideMethod string
- ExpectedMethod string
- }{
- {"POST", "PUT", "PUT"},
- {"POST", "PATCH", "PATCH"},
- {"POST", "DELETE", "DELETE"},
- {"PUT", "DELETE", "PUT"},
- {"GET", "GET", "GET"},
- {"HEAD", "HEAD", "HEAD"},
- {"GET", "PUT", "GET"},
- {"HEAD", "DELETE", "HEAD"},
- }
-
- for _, test := range tests {
- h := HTTPMethodOverrideHandler(okHandler)
- reqs := make([]*http.Request, 0, 2)
-
- rHeader, err := http.NewRequest(test.Method, "/", nil)
- if err != nil {
- t.Error(err)
- }
- rHeader.Header.Set(HTTPMethodOverrideHeader, test.OverrideMethod)
- reqs = append(reqs, rHeader)
-
- f := url.Values{HTTPMethodOverrideFormKey: []string{test.OverrideMethod}}
- rForm, err := http.NewRequest(test.Method, "/", strings.NewReader(f.Encode()))
- if err != nil {
- t.Error(err)
- }
- rForm.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- reqs = append(reqs, rForm)
-
- for _, r := range reqs {
- w := httptest.NewRecorder()
- h.ServeHTTP(w, r)
- if r.Method != test.ExpectedMethod {
- t.Errorf("Expected %s, got %s", test.ExpectedMethod, r.Method)
- }
- }
- }
-}
diff --git a/vendor/github.com/gorilla/handlers/proxy_headers_test.go b/vendor/github.com/gorilla/handlers/proxy_headers_test.go
deleted file mode 100644
index 1bd78052d..000000000
--- a/vendor/github.com/gorilla/handlers/proxy_headers_test.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-type headerTable struct {
- key string // header key
- val string // header val
- expected string // expected result
-}
-
-func TestGetIP(t *testing.T) {
- headers := []headerTable{
- {xForwardedFor, "8.8.8.8", "8.8.8.8"}, // Single address
- {xForwardedFor, "8.8.8.8, 8.8.4.4", "8.8.8.8"}, // Multiple
- {xForwardedFor, "[2001:db8:cafe::17]:4711", "[2001:db8:cafe::17]:4711"}, // IPv6 address
- {xForwardedFor, "", ""}, // None
- {xRealIP, "8.8.8.8", "8.8.8.8"}, // Single address
- {xRealIP, "8.8.8.8, 8.8.4.4", "8.8.8.8, 8.8.4.4"}, // Multiple
- {xRealIP, "[2001:db8:cafe::17]:4711", "[2001:db8:cafe::17]:4711"}, // IPv6 address
- {xRealIP, "", ""}, // None
- {forwarded, `for="_gazonk"`, "_gazonk"}, // Hostname
- {forwarded, `For="[2001:db8:cafe::17]:4711`, `[2001:db8:cafe::17]:4711`}, // IPv6 address
- {forwarded, `for=192.0.2.60;proto=http;by=203.0.113.43`, `192.0.2.60`}, // Multiple params
- {forwarded, `for=192.0.2.43, for=198.51.100.17`, "192.0.2.43"}, // Multiple params
- {forwarded, `for="workstation.local",for=198.51.100.17`, "workstation.local"}, // Hostname
- }
-
- for _, v := range headers {
- req := &http.Request{
- Header: http.Header{
- v.key: []string{v.val},
- }}
- res := getIP(req)
- if res != v.expected {
- t.Fatalf("wrong header for %s: got %s want %s", v.key, res,
- v.expected)
- }
- }
-}
-
-func TestGetScheme(t *testing.T) {
- headers := []headerTable{
- {xForwardedProto, "https", "https"},
- {xForwardedProto, "http", "http"},
- {xForwardedProto, "HTTP", "http"},
- {xForwardedScheme, "https", "https"},
- {xForwardedScheme, "http", "http"},
- {xForwardedScheme, "HTTP", "http"},
- {forwarded, `For="[2001:db8:cafe::17]:4711`, ""}, // No proto
- {forwarded, `for=192.0.2.43, for=198.51.100.17;proto=https`, "https"}, // Multiple params before proto
- {forwarded, `for=172.32.10.15; proto=https;by=127.0.0.1`, "https"}, // Space before proto
- {forwarded, `for=192.0.2.60;proto=http;by=203.0.113.43`, "http"}, // Multiple params
- }
-
- for _, v := range headers {
- req := &http.Request{
- Header: http.Header{
- v.key: []string{v.val},
- },
- }
- res := getScheme(req)
- if res != v.expected {
- t.Fatalf("wrong header for %s: got %s want %s", v.key, res,
- v.expected)
- }
- }
-}
-
-// Test the middleware end-to-end
-func TestProxyHeaders(t *testing.T) {
- rr := httptest.NewRecorder()
- r := newRequest("GET", "/")
-
- r.Header.Set(xForwardedFor, "8.8.8.8")
- r.Header.Set(xForwardedProto, "https")
- r.Header.Set(xForwardedHost, "google.com")
- var (
- addr string
- proto string
- host string
- )
- ProxyHeaders(http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- addr = r.RemoteAddr
- proto = r.URL.Scheme
- host = r.Host
- })).ServeHTTP(rr, r)
-
- if rr.Code != http.StatusOK {
- t.Fatalf("bad status: got %d want %d", rr.Code, http.StatusOK)
- }
-
- if addr != r.Header.Get(xForwardedFor) {
- t.Fatalf("wrong address: got %s want %s", addr,
- r.Header.Get(xForwardedFor))
- }
-
- if proto != r.Header.Get(xForwardedProto) {
- t.Fatalf("wrong address: got %s want %s", proto,
- r.Header.Get(xForwardedProto))
- }
- if host != r.Header.Get(xForwardedHost) {
- t.Fatalf("wrong address: got %s want %s", host,
- r.Header.Get(xForwardedHost))
- }
-
-}
diff --git a/vendor/github.com/gorilla/handlers/recovery_test.go b/vendor/github.com/gorilla/handlers/recovery_test.go
deleted file mode 100644
index 1ae0e5805..000000000
--- a/vendor/github.com/gorilla/handlers/recovery_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package handlers
-
-import (
- "bytes"
- "log"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
-)
-
-func TestRecoveryLoggerWithDefaultOptions(t *testing.T) {
- var buf bytes.Buffer
- log.SetOutput(&buf)
-
- handler := RecoveryHandler()
- handlerFunc := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- panic("Unexpected error!")
- })
-
- recovery := handler(handlerFunc)
- recovery.ServeHTTP(httptest.NewRecorder(), newRequest("GET", "/subdir/asdf"))
-
- if !strings.Contains(buf.String(), "Unexpected error!") {
- t.Fatalf("Got log %#v, wanted substring %#v", buf.String(), "Unexpected error!")
- }
-}
-
-func TestRecoveryLoggerWithCustomLogger(t *testing.T) {
- var buf bytes.Buffer
- var logger = log.New(&buf, "", log.LstdFlags)
-
- handler := RecoveryHandler(RecoveryLogger(logger), PrintRecoveryStack(false))
- handlerFunc := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- panic("Unexpected error!")
- })
-
- recovery := handler(handlerFunc)
- recovery.ServeHTTP(httptest.NewRecorder(), newRequest("GET", "/subdir/asdf"))
-
- if !strings.Contains(buf.String(), "Unexpected error!") {
- t.Fatalf("Got log %#v, wanted substring %#v", buf.String(), "Unexpected error!")
- }
-}
diff --git a/vendor/github.com/gorilla/mux/bench_test.go b/vendor/github.com/gorilla/mux/bench_test.go
deleted file mode 100644
index 522156dcc..000000000
--- a/vendor/github.com/gorilla/mux/bench_test.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2012 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 mux
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-func BenchmarkMux(b *testing.B) {
- router := new(Router)
- handler := func(w http.ResponseWriter, r *http.Request) {}
- router.HandleFunc("/v1/{v1}", handler)
-
- request, _ := http.NewRequest("GET", "/v1/anything", nil)
- for i := 0; i < b.N; i++ {
- router.ServeHTTP(nil, request)
- }
-}
-
-func BenchmarkMuxAlternativeInRegexp(b *testing.B) {
- router := new(Router)
- handler := func(w http.ResponseWriter, r *http.Request) {}
- router.HandleFunc("/v1/{v1:(?:a|b)}", handler)
-
- requestA, _ := http.NewRequest("GET", "/v1/a", nil)
- requestB, _ := http.NewRequest("GET", "/v1/b", nil)
- for i := 0; i < b.N; i++ {
- router.ServeHTTP(nil, requestA)
- router.ServeHTTP(nil, requestB)
- }
-}
-
-func BenchmarkManyPathVariables(b *testing.B) {
- router := new(Router)
- handler := func(w http.ResponseWriter, r *http.Request) {}
- router.HandleFunc("/v1/{v1}/{v2}/{v3}/{v4}/{v5}", handler)
-
- matchingRequest, _ := http.NewRequest("GET", "/v1/1/2/3/4/5", nil)
- notMatchingRequest, _ := http.NewRequest("GET", "/v1/1/2/3/4", nil)
- recorder := httptest.NewRecorder()
- for i := 0; i < b.N; i++ {
- router.ServeHTTP(nil, matchingRequest)
- router.ServeHTTP(recorder, notMatchingRequest)
- }
-}
diff --git a/vendor/github.com/gorilla/mux/context_gorilla_test.go b/vendor/github.com/gorilla/mux/context_gorilla_test.go
deleted file mode 100644
index ffaf384c0..000000000
--- a/vendor/github.com/gorilla/mux/context_gorilla_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// +build !go1.7
-
-package mux
-
-import (
- "net/http"
- "testing"
-
- "github.com/gorilla/context"
-)
-
-// Tests that the context is cleared or not cleared properly depending on
-// the configuration of the router
-func TestKeepContext(t *testing.T) {
- func1 := func(w http.ResponseWriter, r *http.Request) {}
-
- r := NewRouter()
- r.HandleFunc("/", func1).Name("func1")
-
- req, _ := http.NewRequest("GET", "http://localhost/", nil)
- context.Set(req, "t", 1)
-
- res := new(http.ResponseWriter)
- r.ServeHTTP(*res, req)
-
- if _, ok := context.GetOk(req, "t"); ok {
- t.Error("Context should have been cleared at end of request")
- }
-
- r.KeepContext = true
-
- req, _ = http.NewRequest("GET", "http://localhost/", nil)
- context.Set(req, "t", 1)
-
- r.ServeHTTP(*res, req)
- if _, ok := context.GetOk(req, "t"); !ok {
- t.Error("Context should NOT have been cleared at end of request")
- }
-
-}
diff --git a/vendor/github.com/gorilla/mux/context_native_test.go b/vendor/github.com/gorilla/mux/context_native_test.go
deleted file mode 100644
index c150edf01..000000000
--- a/vendor/github.com/gorilla/mux/context_native_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// +build go1.7
-
-package mux
-
-import (
- "context"
- "net/http"
- "testing"
- "time"
-)
-
-func TestNativeContextMiddleware(t *testing.T) {
- withTimeout := func(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
- defer cancel()
- h.ServeHTTP(w, r.WithContext(ctx))
- })
- }
-
- r := NewRouter()
- r.Handle("/path/{foo}", withTimeout(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- vars := Vars(r)
- if vars["foo"] != "bar" {
- t.Fatal("Expected foo var to be set")
- }
- })))
-
- rec := NewRecorder()
- req := newRequest("GET", "/path/bar")
- r.ServeHTTP(rec, req)
-}
diff --git a/vendor/github.com/gorilla/mux/example_route_test.go b/vendor/github.com/gorilla/mux/example_route_test.go
deleted file mode 100644
index 112557071..000000000
--- a/vendor/github.com/gorilla/mux/example_route_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package mux_test
-
-import (
- "fmt"
- "net/http"
-
- "github.com/gorilla/mux"
-)
-
-// This example demonstrates setting a regular expression matcher for
-// the header value. A plain word will match any value that contains a
-// matching substring as if the pattern was wrapped with `.*`.
-func ExampleRoute_HeadersRegexp() {
- r := mux.NewRouter()
- route := r.NewRoute().HeadersRegexp("Accept", "html")
-
- req1, _ := http.NewRequest("GET", "example.com", nil)
- req1.Header.Add("Accept", "text/plain")
- req1.Header.Add("Accept", "text/html")
-
- req2, _ := http.NewRequest("GET", "example.com", nil)
- req2.Header.Set("Accept", "application/xhtml+xml")
-
- matchInfo := &mux.RouteMatch{}
- fmt.Printf("Match: %v %q\n", route.Match(req1, matchInfo), req1.Header["Accept"])
- fmt.Printf("Match: %v %q\n", route.Match(req2, matchInfo), req2.Header["Accept"])
- // Output:
- // Match: true ["text/plain" "text/html"]
- // Match: true ["application/xhtml+xml"]
-}
-
-// This example demonstrates setting a strict regular expression matcher
-// for the header value. Using the start and end of string anchors, the
-// value must be an exact match.
-func ExampleRoute_HeadersRegexp_exactMatch() {
- r := mux.NewRouter()
- route := r.NewRoute().HeadersRegexp("Origin", "^https://example.co$")
-
- yes, _ := http.NewRequest("GET", "example.co", nil)
- yes.Header.Set("Origin", "https://example.co")
-
- no, _ := http.NewRequest("GET", "example.co.uk", nil)
- no.Header.Set("Origin", "https://example.co.uk")
-
- matchInfo := &mux.RouteMatch{}
- fmt.Printf("Match: %v %q\n", route.Match(yes, matchInfo), yes.Header["Origin"])
- fmt.Printf("Match: %v %q\n", route.Match(no, matchInfo), no.Header["Origin"])
- // Output:
- // Match: true ["https://example.co"]
- // Match: false ["https://example.co.uk"]
-}
diff --git a/vendor/github.com/gorilla/mux/middleware_test.go b/vendor/github.com/gorilla/mux/middleware_test.go
deleted file mode 100644
index 93947e8cb..000000000
--- a/vendor/github.com/gorilla/mux/middleware_test.go
+++ /dev/null
@@ -1,336 +0,0 @@
-package mux
-
-import (
- "bytes"
- "net/http"
- "testing"
-)
-
-type testMiddleware struct {
- timesCalled uint
-}
-
-func (tm *testMiddleware) Middleware(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- tm.timesCalled++
- h.ServeHTTP(w, r)
- })
-}
-
-func dummyHandler(w http.ResponseWriter, r *http.Request) {}
-
-func TestMiddlewareAdd(t *testing.T) {
- router := NewRouter()
- router.HandleFunc("/", dummyHandler).Methods("GET")
-
- mw := &testMiddleware{}
-
- router.useInterface(mw)
- if len(router.middlewares) != 1 || router.middlewares[0] != mw {
- t.Fatal("Middleware was not added correctly")
- }
-
- router.Use(mw.Middleware)
- if len(router.middlewares) != 2 {
- t.Fatal("MiddlewareFunc method was not added correctly")
- }
-
- banalMw := func(handler http.Handler) http.Handler {
- return handler
- }
- router.Use(banalMw)
- if len(router.middlewares) != 3 {
- t.Fatal("MiddlewareFunc method was not added correctly")
- }
-}
-
-func TestMiddleware(t *testing.T) {
- router := NewRouter()
- router.HandleFunc("/", dummyHandler).Methods("GET")
-
- mw := &testMiddleware{}
- router.useInterface(mw)
-
- rw := NewRecorder()
- req := newRequest("GET", "/")
-
- // Test regular middleware call
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 1 {
- t.Fatalf("Expected %d calls, but got only %d", 1, mw.timesCalled)
- }
-
- // Middleware should not be called for 404
- req = newRequest("GET", "/not/found")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 1 {
- t.Fatalf("Expected %d calls, but got only %d", 1, mw.timesCalled)
- }
-
- // Middleware should not be called if there is a method mismatch
- req = newRequest("POST", "/")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 1 {
- t.Fatalf("Expected %d calls, but got only %d", 1, mw.timesCalled)
- }
-
- // Add the middleware again as function
- router.Use(mw.Middleware)
- req = newRequest("GET", "/")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 3 {
- t.Fatalf("Expected %d calls, but got only %d", 3, mw.timesCalled)
- }
-
-}
-
-func TestMiddlewareSubrouter(t *testing.T) {
- router := NewRouter()
- router.HandleFunc("/", dummyHandler).Methods("GET")
-
- subrouter := router.PathPrefix("/sub").Subrouter()
- subrouter.HandleFunc("/x", dummyHandler).Methods("GET")
-
- mw := &testMiddleware{}
- subrouter.useInterface(mw)
-
- rw := NewRecorder()
- req := newRequest("GET", "/")
-
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 0 {
- t.Fatalf("Expected %d calls, but got only %d", 0, mw.timesCalled)
- }
-
- req = newRequest("GET", "/sub/")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 0 {
- t.Fatalf("Expected %d calls, but got only %d", 0, mw.timesCalled)
- }
-
- req = newRequest("GET", "/sub/x")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 1 {
- t.Fatalf("Expected %d calls, but got only %d", 1, mw.timesCalled)
- }
-
- req = newRequest("GET", "/sub/not/found")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 1 {
- t.Fatalf("Expected %d calls, but got only %d", 1, mw.timesCalled)
- }
-
- router.useInterface(mw)
-
- req = newRequest("GET", "/")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 2 {
- t.Fatalf("Expected %d calls, but got only %d", 2, mw.timesCalled)
- }
-
- req = newRequest("GET", "/sub/x")
- router.ServeHTTP(rw, req)
- if mw.timesCalled != 4 {
- t.Fatalf("Expected %d calls, but got only %d", 4, mw.timesCalled)
- }
-}
-
-func TestMiddlewareExecution(t *testing.T) {
- mwStr := []byte("Middleware\n")
- handlerStr := []byte("Logic\n")
-
- router := NewRouter()
- router.HandleFunc("/", func(w http.ResponseWriter, e *http.Request) {
- w.Write(handlerStr)
- })
-
- rw := NewRecorder()
- req := newRequest("GET", "/")
-
- // Test handler-only call
- router.ServeHTTP(rw, req)
-
- if bytes.Compare(rw.Body.Bytes(), handlerStr) != 0 {
- t.Fatal("Handler response is not what it should be")
- }
-
- // Test middleware call
- rw = NewRecorder()
-
- router.Use(func(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write(mwStr)
- h.ServeHTTP(w, r)
- })
- })
-
- router.ServeHTTP(rw, req)
- if bytes.Compare(rw.Body.Bytes(), append(mwStr, handlerStr...)) != 0 {
- t.Fatal("Middleware + handler response is not what it should be")
- }
-}
-
-func TestMiddlewareNotFound(t *testing.T) {
- mwStr := []byte("Middleware\n")
- handlerStr := []byte("Logic\n")
-
- router := NewRouter()
- router.HandleFunc("/", func(w http.ResponseWriter, e *http.Request) {
- w.Write(handlerStr)
- })
- router.Use(func(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write(mwStr)
- h.ServeHTTP(w, r)
- })
- })
-
- // Test not found call with default handler
- rw := NewRecorder()
- req := newRequest("GET", "/notfound")
-
- router.ServeHTTP(rw, req)
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a 404")
- }
-
- // Test not found call with custom handler
- rw = NewRecorder()
- req = newRequest("GET", "/notfound")
-
- router.NotFoundHandler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
- rw.Write([]byte("Custom 404 handler"))
- })
- router.ServeHTTP(rw, req)
-
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a custom 404")
- }
-}
-
-func TestMiddlewareMethodMismatch(t *testing.T) {
- mwStr := []byte("Middleware\n")
- handlerStr := []byte("Logic\n")
-
- router := NewRouter()
- router.HandleFunc("/", func(w http.ResponseWriter, e *http.Request) {
- w.Write(handlerStr)
- }).Methods("GET")
-
- router.Use(func(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write(mwStr)
- h.ServeHTTP(w, r)
- })
- })
-
- // Test method mismatch
- rw := NewRecorder()
- req := newRequest("POST", "/")
-
- router.ServeHTTP(rw, req)
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a method mismatch")
- }
-
- // Test not found call
- rw = NewRecorder()
- req = newRequest("POST", "/")
-
- router.MethodNotAllowedHandler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
- rw.Write([]byte("Method not allowed"))
- })
- router.ServeHTTP(rw, req)
-
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a method mismatch")
- }
-}
-
-func TestMiddlewareNotFoundSubrouter(t *testing.T) {
- mwStr := []byte("Middleware\n")
- handlerStr := []byte("Logic\n")
-
- router := NewRouter()
- router.HandleFunc("/", func(w http.ResponseWriter, e *http.Request) {
- w.Write(handlerStr)
- })
-
- subrouter := router.PathPrefix("/sub/").Subrouter()
- subrouter.HandleFunc("/", func(w http.ResponseWriter, e *http.Request) {
- w.Write(handlerStr)
- })
-
- router.Use(func(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write(mwStr)
- h.ServeHTTP(w, r)
- })
- })
-
- // Test not found call for default handler
- rw := NewRecorder()
- req := newRequest("GET", "/sub/notfound")
-
- router.ServeHTTP(rw, req)
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a 404")
- }
-
- // Test not found call with custom handler
- rw = NewRecorder()
- req = newRequest("GET", "/sub/notfound")
-
- subrouter.NotFoundHandler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
- rw.Write([]byte("Custom 404 handler"))
- })
- router.ServeHTTP(rw, req)
-
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a custom 404")
- }
-}
-
-func TestMiddlewareMethodMismatchSubrouter(t *testing.T) {
- mwStr := []byte("Middleware\n")
- handlerStr := []byte("Logic\n")
-
- router := NewRouter()
- router.HandleFunc("/", func(w http.ResponseWriter, e *http.Request) {
- w.Write(handlerStr)
- })
-
- subrouter := router.PathPrefix("/sub/").Subrouter()
- subrouter.HandleFunc("/", func(w http.ResponseWriter, e *http.Request) {
- w.Write(handlerStr)
- }).Methods("GET")
-
- router.Use(func(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write(mwStr)
- h.ServeHTTP(w, r)
- })
- })
-
- // Test method mismatch without custom handler
- rw := NewRecorder()
- req := newRequest("POST", "/sub/")
-
- router.ServeHTTP(rw, req)
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a method mismatch")
- }
-
- // Test method mismatch with custom handler
- rw = NewRecorder()
- req = newRequest("POST", "/sub/")
-
- router.MethodNotAllowedHandler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
- rw.Write([]byte("Method not allowed"))
- })
- router.ServeHTTP(rw, req)
-
- if bytes.Contains(rw.Body.Bytes(), mwStr) {
- t.Fatal("Middleware was called for a method mismatch")
- }
-}
diff --git a/vendor/github.com/gorilla/mux/mux_test.go b/vendor/github.com/gorilla/mux/mux_test.go
deleted file mode 100644
index 9e93c9830..000000000
--- a/vendor/github.com/gorilla/mux/mux_test.go
+++ /dev/null
@@ -1,2347 +0,0 @@
-// Copyright 2012 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 mux
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "net/http"
- "net/url"
- "reflect"
- "strings"
- "testing"
-)
-
-func (r *Route) GoString() string {
- matchers := make([]string, len(r.matchers))
- for i, m := range r.matchers {
- matchers[i] = fmt.Sprintf("%#v", m)
- }
- return fmt.Sprintf("&Route{matchers:[]matcher{%s}}", strings.Join(matchers, ", "))
-}
-
-func (r *routeRegexp) GoString() string {
- return fmt.Sprintf("&routeRegexp{template: %q, regexpType: %v, options: %v, regexp: regexp.MustCompile(%q), reverse: %q, varsN: %v, varsR: %v", r.template, r.regexpType, r.options, r.regexp.String(), r.reverse, r.varsN, r.varsR)
-}
-
-type routeTest struct {
- title string // title of the test
- route *Route // the route being tested
- request *http.Request // a request to test the route
- vars map[string]string // the expected vars of the match
- scheme string // the expected scheme of the built URL
- host string // the expected host of the built URL
- path string // the expected path of the built URL
- query string // the expected query string of the built URL
- pathTemplate string // the expected path template of the route
- hostTemplate string // the expected host template of the route
- queriesTemplate string // the expected query template of the route
- methods []string // the expected route methods
- pathRegexp string // the expected path regexp
- queriesRegexp string // the expected query regexp
- shouldMatch bool // whether the request is expected to match the route at all
- shouldRedirect bool // whether the request should result in a redirect
-}
-
-func TestHost(t *testing.T) {
- // newRequestHost a new request with a method, url, and host header
- newRequestHost := func(method, url, host string) *http.Request {
- req, err := http.NewRequest(method, url, nil)
- if err != nil {
- panic(err)
- }
- req.Host = host
- return req
- }
-
- tests := []routeTest{
- {
- title: "Host route match",
- route: new(Route).Host("aaa.bbb.ccc"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{},
- host: "aaa.bbb.ccc",
- path: "",
- shouldMatch: true,
- },
- {
- title: "Host route, wrong host in request URL",
- route: new(Route).Host("aaa.bbb.ccc"),
- request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
- vars: map[string]string{},
- host: "aaa.bbb.ccc",
- path: "",
- shouldMatch: false,
- },
- {
- title: "Host route with port, match",
- route: new(Route).Host("aaa.bbb.ccc:1234"),
- request: newRequest("GET", "http://aaa.bbb.ccc:1234/111/222/333"),
- vars: map[string]string{},
- host: "aaa.bbb.ccc:1234",
- path: "",
- shouldMatch: true,
- },
- {
- title: "Host route with port, wrong port in request URL",
- route: new(Route).Host("aaa.bbb.ccc:1234"),
- request: newRequest("GET", "http://aaa.bbb.ccc:9999/111/222/333"),
- vars: map[string]string{},
- host: "aaa.bbb.ccc:1234",
- path: "",
- shouldMatch: false,
- },
- {
- title: "Host route, match with host in request header",
- route: new(Route).Host("aaa.bbb.ccc"),
- request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc"),
- vars: map[string]string{},
- host: "aaa.bbb.ccc",
- path: "",
- shouldMatch: true,
- },
- {
- title: "Host route, wrong host in request header",
- route: new(Route).Host("aaa.bbb.ccc"),
- request: newRequestHost("GET", "/111/222/333", "aaa.222.ccc"),
- vars: map[string]string{},
- host: "aaa.bbb.ccc",
- path: "",
- shouldMatch: false,
- },
- // BUG {new(Route).Host("aaa.bbb.ccc:1234"), newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:1234"), map[string]string{}, "aaa.bbb.ccc:1234", "", true},
- {
- title: "Host route with port, wrong host in request header",
- route: new(Route).Host("aaa.bbb.ccc:1234"),
- request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:9999"),
- vars: map[string]string{},
- host: "aaa.bbb.ccc:1234",
- path: "",
- shouldMatch: false,
- },
- {
- title: "Host route with pattern, match",
- route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v1": "bbb"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `aaa.{v1:[a-z]{3}}.ccc`,
- shouldMatch: true,
- },
- {
- title: "Host route with pattern, additional capturing group, match",
- route: new(Route).Host("aaa.{v1:[a-z]{2}(?:b|c)}.ccc"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v1": "bbb"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `aaa.{v1:[a-z]{2}(?:b|c)}.ccc`,
- shouldMatch: true,
- },
- {
- title: "Host route with pattern, wrong host in request URL",
- route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"),
- request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
- vars: map[string]string{"v1": "bbb"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `aaa.{v1:[a-z]{3}}.ccc`,
- shouldMatch: false,
- },
- {
- title: "Host route with multiple patterns, match",
- route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}`,
- shouldMatch: true,
- },
- {
- title: "Host route with multiple patterns, wrong host in request URL",
- route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"),
- request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
- vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}`,
- shouldMatch: false,
- },
- {
- title: "Host route with hyphenated name and pattern, match",
- route: new(Route).Host("aaa.{v-1:[a-z]{3}}.ccc"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v-1": "bbb"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `aaa.{v-1:[a-z]{3}}.ccc`,
- shouldMatch: true,
- },
- {
- title: "Host route with hyphenated name and pattern, additional capturing group, match",
- route: new(Route).Host("aaa.{v-1:[a-z]{2}(?:b|c)}.ccc"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v-1": "bbb"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `aaa.{v-1:[a-z]{2}(?:b|c)}.ccc`,
- shouldMatch: true,
- },
- {
- title: "Host route with multiple hyphenated names and patterns, match",
- route: new(Route).Host("{v-1:[a-z]{3}}.{v-2:[a-z]{3}}.{v-3:[a-z]{3}}"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v-1": "aaa", "v-2": "bbb", "v-3": "ccc"},
- host: "aaa.bbb.ccc",
- path: "",
- hostTemplate: `{v-1:[a-z]{3}}.{v-2:[a-z]{3}}.{v-3:[a-z]{3}}`,
- shouldMatch: true,
- },
- }
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- }
-}
-
-func TestPath(t *testing.T) {
- tests := []routeTest{
- {
- title: "Path route, match",
- route: new(Route).Path("/111/222/333"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{},
- host: "",
- path: "/111/222/333",
- shouldMatch: true,
- },
- {
- title: "Path route, match with trailing slash in request and path",
- route: new(Route).Path("/111/"),
- request: newRequest("GET", "http://localhost/111/"),
- vars: map[string]string{},
- host: "",
- path: "/111/",
- shouldMatch: true,
- },
- {
- title: "Path route, do not match with trailing slash in path",
- route: new(Route).Path("/111/"),
- request: newRequest("GET", "http://localhost/111"),
- vars: map[string]string{},
- host: "",
- path: "/111",
- pathTemplate: `/111/`,
- pathRegexp: `^/111/$`,
- shouldMatch: false,
- },
- {
- title: "Path route, do not match with trailing slash in request",
- route: new(Route).Path("/111"),
- request: newRequest("GET", "http://localhost/111/"),
- vars: map[string]string{},
- host: "",
- path: "/111/",
- pathTemplate: `/111`,
- shouldMatch: false,
- },
- {
- title: "Path route, match root with no host",
- route: new(Route).Path("/"),
- request: newRequest("GET", "/"),
- vars: map[string]string{},
- host: "",
- path: "/",
- pathTemplate: `/`,
- pathRegexp: `^/$`,
- shouldMatch: true,
- },
- {
- title: "Path route, match root with no host, App Engine format",
- route: new(Route).Path("/"),
- request: func() *http.Request {
- r := newRequest("GET", "http://localhost/")
- r.RequestURI = "/"
- return r
- }(),
- vars: map[string]string{},
- host: "",
- path: "/",
- pathTemplate: `/`,
- shouldMatch: true,
- },
- {
- title: "Path route, wrong path in request in request URL",
- route: new(Route).Path("/111/222/333"),
- request: newRequest("GET", "http://localhost/1/2/3"),
- vars: map[string]string{},
- host: "",
- path: "/111/222/333",
- shouldMatch: false,
- },
- {
- title: "Path route with pattern, match",
- route: new(Route).Path("/111/{v1:[0-9]{3}}/333"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{"v1": "222"},
- host: "",
- path: "/111/222/333",
- pathTemplate: `/111/{v1:[0-9]{3}}/333`,
- shouldMatch: true,
- },
- {
- title: "Path route with pattern, URL in request does not match",
- route: new(Route).Path("/111/{v1:[0-9]{3}}/333"),
- request: newRequest("GET", "http://localhost/111/aaa/333"),
- vars: map[string]string{"v1": "222"},
- host: "",
- path: "/111/222/333",
- pathTemplate: `/111/{v1:[0-9]{3}}/333`,
- pathRegexp: `^/111/(?P<v0>[0-9]{3})/333$`,
- shouldMatch: false,
- },
- {
- title: "Path route with multiple patterns, match",
- route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"},
- host: "",
- path: "/111/222/333",
- pathTemplate: `/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}`,
- pathRegexp: `^/(?P<v0>[0-9]{3})/(?P<v1>[0-9]{3})/(?P<v2>[0-9]{3})$`,
- shouldMatch: true,
- },
- {
- title: "Path route with multiple patterns, URL in request does not match",
- route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"),
- request: newRequest("GET", "http://localhost/111/aaa/333"),
- vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"},
- host: "",
- path: "/111/222/333",
- pathTemplate: `/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}`,
- pathRegexp: `^/(?P<v0>[0-9]{3})/(?P<v1>[0-9]{3})/(?P<v2>[0-9]{3})$`,
- shouldMatch: false,
- },
- {
- title: "Path route with multiple patterns with pipe, match",
- route: new(Route).Path("/{category:a|(?:b/c)}/{product}/{id:[0-9]+}"),
- request: newRequest("GET", "http://localhost/a/product_name/1"),
- vars: map[string]string{"category": "a", "product": "product_name", "id": "1"},
- host: "",
- path: "/a/product_name/1",
- pathTemplate: `/{category:a|(?:b/c)}/{product}/{id:[0-9]+}`,
- pathRegexp: `^/(?P<v0>a|(?:b/c))/(?P<v1>[^/]+)/(?P<v2>[0-9]+)$`,
- shouldMatch: true,
- },
- {
- title: "Path route with hyphenated name and pattern, match",
- route: new(Route).Path("/111/{v-1:[0-9]{3}}/333"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{"v-1": "222"},
- host: "",
- path: "/111/222/333",
- pathTemplate: `/111/{v-1:[0-9]{3}}/333`,
- pathRegexp: `^/111/(?P<v0>[0-9]{3})/333$`,
- shouldMatch: true,
- },
- {
- title: "Path route with multiple hyphenated names and patterns, match",
- route: new(Route).Path("/{v-1:[0-9]{3}}/{v-2:[0-9]{3}}/{v-3:[0-9]{3}}"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{"v-1": "111", "v-2": "222", "v-3": "333"},
- host: "",
- path: "/111/222/333",
- pathTemplate: `/{v-1:[0-9]{3}}/{v-2:[0-9]{3}}/{v-3:[0-9]{3}}`,
- pathRegexp: `^/(?P<v0>[0-9]{3})/(?P<v1>[0-9]{3})/(?P<v2>[0-9]{3})$`,
- shouldMatch: true,
- },
- {
- title: "Path route with multiple hyphenated names and patterns with pipe, match",
- route: new(Route).Path("/{product-category:a|(?:b/c)}/{product-name}/{product-id:[0-9]+}"),
- request: newRequest("GET", "http://localhost/a/product_name/1"),
- vars: map[string]string{"product-category": "a", "product-name": "product_name", "product-id": "1"},
- host: "",
- path: "/a/product_name/1",
- pathTemplate: `/{product-category:a|(?:b/c)}/{product-name}/{product-id:[0-9]+}`,
- pathRegexp: `^/(?P<v0>a|(?:b/c))/(?P<v1>[^/]+)/(?P<v2>[0-9]+)$`,
- shouldMatch: true,
- },
- {
- title: "Path route with multiple hyphenated names and patterns with pipe and case insensitive, match",
- route: new(Route).Path("/{type:(?i:daily|mini|variety)}-{date:\\d{4,4}-\\d{2,2}-\\d{2,2}}"),
- request: newRequest("GET", "http://localhost/daily-2016-01-01"),
- vars: map[string]string{"type": "daily", "date": "2016-01-01"},
- host: "",
- path: "/daily-2016-01-01",
- pathTemplate: `/{type:(?i:daily|mini|variety)}-{date:\d{4,4}-\d{2,2}-\d{2,2}}`,
- pathRegexp: `^/(?P<v0>(?i:daily|mini|variety))-(?P<v1>\d{4,4}-\d{2,2}-\d{2,2})$`,
- shouldMatch: true,
- },
- {
- title: "Path route with empty match right after other match",
- route: new(Route).Path(`/{v1:[0-9]*}{v2:[a-z]*}/{v3:[0-9]*}`),
- request: newRequest("GET", "http://localhost/111/222"),
- vars: map[string]string{"v1": "111", "v2": "", "v3": "222"},
- host: "",
- path: "/111/222",
- pathTemplate: `/{v1:[0-9]*}{v2:[a-z]*}/{v3:[0-9]*}`,
- pathRegexp: `^/(?P<v0>[0-9]*)(?P<v1>[a-z]*)/(?P<v2>[0-9]*)$`,
- shouldMatch: true,
- },
- {
- title: "Path route with single pattern with pipe, match",
- route: new(Route).Path("/{category:a|b/c}"),
- request: newRequest("GET", "http://localhost/a"),
- vars: map[string]string{"category": "a"},
- host: "",
- path: "/a",
- pathTemplate: `/{category:a|b/c}`,
- shouldMatch: true,
- },
- {
- title: "Path route with single pattern with pipe, match",
- route: new(Route).Path("/{category:a|b/c}"),
- request: newRequest("GET", "http://localhost/b/c"),
- vars: map[string]string{"category": "b/c"},
- host: "",
- path: "/b/c",
- pathTemplate: `/{category:a|b/c}`,
- shouldMatch: true,
- },
- {
- title: "Path route with multiple patterns with pipe, match",
- route: new(Route).Path("/{category:a|b/c}/{product}/{id:[0-9]+}"),
- request: newRequest("GET", "http://localhost/a/product_name/1"),
- vars: map[string]string{"category": "a", "product": "product_name", "id": "1"},
- host: "",
- path: "/a/product_name/1",
- pathTemplate: `/{category:a|b/c}/{product}/{id:[0-9]+}`,
- shouldMatch: true,
- },
- {
- title: "Path route with multiple patterns with pipe, match",
- route: new(Route).Path("/{category:a|b/c}/{product}/{id:[0-9]+}"),
- request: newRequest("GET", "http://localhost/b/c/product_name/1"),
- vars: map[string]string{"category": "b/c", "product": "product_name", "id": "1"},
- host: "",
- path: "/b/c/product_name/1",
- pathTemplate: `/{category:a|b/c}/{product}/{id:[0-9]+}`,
- shouldMatch: true,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- testUseEscapedRoute(t, test)
- testRegexp(t, test)
- }
-}
-
-func TestPathPrefix(t *testing.T) {
- tests := []routeTest{
- {
- title: "PathPrefix route, match",
- route: new(Route).PathPrefix("/111"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{},
- host: "",
- path: "/111",
- shouldMatch: true,
- },
- {
- title: "PathPrefix route, match substring",
- route: new(Route).PathPrefix("/1"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{},
- host: "",
- path: "/1",
- shouldMatch: true,
- },
- {
- title: "PathPrefix route, URL prefix in request does not match",
- route: new(Route).PathPrefix("/111"),
- request: newRequest("GET", "http://localhost/1/2/3"),
- vars: map[string]string{},
- host: "",
- path: "/111",
- shouldMatch: false,
- },
- {
- title: "PathPrefix route with pattern, match",
- route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{"v1": "222"},
- host: "",
- path: "/111/222",
- pathTemplate: `/111/{v1:[0-9]{3}}`,
- shouldMatch: true,
- },
- {
- title: "PathPrefix route with pattern, URL prefix in request does not match",
- route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"),
- request: newRequest("GET", "http://localhost/111/aaa/333"),
- vars: map[string]string{"v1": "222"},
- host: "",
- path: "/111/222",
- pathTemplate: `/111/{v1:[0-9]{3}}`,
- shouldMatch: false,
- },
- {
- title: "PathPrefix route with multiple patterns, match",
- route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"),
- request: newRequest("GET", "http://localhost/111/222/333"),
- vars: map[string]string{"v1": "111", "v2": "222"},
- host: "",
- path: "/111/222",
- pathTemplate: `/{v1:[0-9]{3}}/{v2:[0-9]{3}}`,
- shouldMatch: true,
- },
- {
- title: "PathPrefix route with multiple patterns, URL prefix in request does not match",
- route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"),
- request: newRequest("GET", "http://localhost/111/aaa/333"),
- vars: map[string]string{"v1": "111", "v2": "222"},
- host: "",
- path: "/111/222",
- pathTemplate: `/{v1:[0-9]{3}}/{v2:[0-9]{3}}`,
- shouldMatch: false,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- testUseEscapedRoute(t, test)
- }
-}
-
-func TestSchemeHostPath(t *testing.T) {
- tests := []routeTest{
- {
- title: "Host and Path route, match",
- route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{},
- scheme: "http",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/111/222/333`,
- hostTemplate: `aaa.bbb.ccc`,
- shouldMatch: true,
- },
- {
- title: "Scheme, Host, and Path route, match",
- route: new(Route).Schemes("https").Host("aaa.bbb.ccc").Path("/111/222/333"),
- request: newRequest("GET", "https://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{},
- scheme: "https",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/111/222/333`,
- hostTemplate: `aaa.bbb.ccc`,
- shouldMatch: true,
- },
- {
- title: "Host and Path route, wrong host in request URL",
- route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"),
- request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
- vars: map[string]string{},
- scheme: "http",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/111/222/333`,
- hostTemplate: `aaa.bbb.ccc`,
- shouldMatch: false,
- },
- {
- title: "Host and Path route with pattern, match",
- route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v1": "bbb", "v2": "222"},
- scheme: "http",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/111/{v2:[0-9]{3}}/333`,
- hostTemplate: `aaa.{v1:[a-z]{3}}.ccc`,
- shouldMatch: true,
- },
- {
- title: "Scheme, Host, and Path route with host and path patterns, match",
- route: new(Route).Schemes("ftp", "ssss").Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"),
- request: newRequest("GET", "ssss://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v1": "bbb", "v2": "222"},
- scheme: "ftp",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/111/{v2:[0-9]{3}}/333`,
- hostTemplate: `aaa.{v1:[a-z]{3}}.ccc`,
- shouldMatch: true,
- },
- {
- title: "Host and Path route with pattern, URL in request does not match",
- route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"),
- request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
- vars: map[string]string{"v1": "bbb", "v2": "222"},
- scheme: "http",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/111/{v2:[0-9]{3}}/333`,
- hostTemplate: `aaa.{v1:[a-z]{3}}.ccc`,
- shouldMatch: false,
- },
- {
- title: "Host and Path route with multiple patterns, match",
- route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"),
- request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"),
- vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"},
- scheme: "http",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}`,
- hostTemplate: `{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}`,
- shouldMatch: true,
- },
- {
- title: "Host and Path route with multiple patterns, URL in request does not match",
- route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"),
- request: newRequest("GET", "http://aaa.222.ccc/111/222/333"),
- vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"},
- scheme: "http",
- host: "aaa.bbb.ccc",
- path: "/111/222/333",
- pathTemplate: `/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}`,
- hostTemplate: `{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}`,
- shouldMatch: false,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- testUseEscapedRoute(t, test)
- }
-}
-
-func TestHeaders(t *testing.T) {
- // newRequestHeaders creates a new request with a method, url, and headers
- newRequestHeaders := func(method, url string, headers map[string]string) *http.Request {
- req, err := http.NewRequest(method, url, nil)
- if err != nil {
- panic(err)
- }
- for k, v := range headers {
- req.Header.Add(k, v)
- }
- return req
- }
-
- tests := []routeTest{
- {
- title: "Headers route, match",
- route: new(Route).Headers("foo", "bar", "baz", "ding"),
- request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "ding"}),
- vars: map[string]string{},
- host: "",
- path: "",
- shouldMatch: true,
- },
- {
- title: "Headers route, bad header values",
- route: new(Route).Headers("foo", "bar", "baz", "ding"),
- request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "dong"}),
- vars: map[string]string{},
- host: "",
- path: "",
- shouldMatch: false,
- },
- {
- title: "Headers route, regex header values to match",
- route: new(Route).Headers("foo", "ba[zr]"),
- request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar"}),
- vars: map[string]string{},
- host: "",
- path: "",
- shouldMatch: false,
- },
- {
- title: "Headers route, regex header values to match",
- route: new(Route).HeadersRegexp("foo", "ba[zr]"),
- request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "baz"}),
- vars: map[string]string{},
- host: "",
- path: "",
- shouldMatch: true,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- }
-}
-
-func TestMethods(t *testing.T) {
- tests := []routeTest{
- {
- title: "Methods route, match GET",
- route: new(Route).Methods("GET", "POST"),
- request: newRequest("GET", "http://localhost"),
- vars: map[string]string{},
- host: "",
- path: "",
- methods: []string{"GET", "POST"},
- shouldMatch: true,
- },
- {
- title: "Methods route, match POST",
- route: new(Route).Methods("GET", "POST"),
- request: newRequest("POST", "http://localhost"),
- vars: map[string]string{},
- host: "",
- path: "",
- methods: []string{"GET", "POST"},
- shouldMatch: true,
- },
- {
- title: "Methods route, bad method",
- route: new(Route).Methods("GET", "POST"),
- request: newRequest("PUT", "http://localhost"),
- vars: map[string]string{},
- host: "",
- path: "",
- methods: []string{"GET", "POST"},
- shouldMatch: false,
- },
- {
- title: "Route without methods",
- route: new(Route),
- request: newRequest("PUT", "http://localhost"),
- vars: map[string]string{},
- host: "",
- path: "",
- methods: []string{},
- shouldMatch: true,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- testMethods(t, test)
- }
-}
-
-func TestQueries(t *testing.T) {
- tests := []routeTest{
- {
- title: "Queries route, match",
- route: new(Route).Queries("foo", "bar", "baz", "ding"),
- request: newRequest("GET", "http://localhost?foo=bar&baz=ding"),
- vars: map[string]string{},
- host: "",
- path: "",
- query: "foo=bar&baz=ding",
- queriesTemplate: "foo=bar,baz=ding",
- queriesRegexp: "^foo=bar$,^baz=ding$",
- shouldMatch: true,
- },
- {
- title: "Queries route, match with a query string",
- route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"),
- request: newRequest("GET", "http://www.example.com/api?foo=bar&baz=ding"),
- vars: map[string]string{},
- host: "",
- path: "",
- query: "foo=bar&baz=ding",
- pathTemplate: `/api`,
- hostTemplate: `www.example.com`,
- queriesTemplate: "foo=bar,baz=ding",
- queriesRegexp: "^foo=bar$,^baz=ding$",
- shouldMatch: true,
- },
- {
- title: "Queries route, match with a query string out of order",
- route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"),
- request: newRequest("GET", "http://www.example.com/api?baz=ding&foo=bar"),
- vars: map[string]string{},
- host: "",
- path: "",
- query: "foo=bar&baz=ding",
- pathTemplate: `/api`,
- hostTemplate: `www.example.com`,
- queriesTemplate: "foo=bar,baz=ding",
- queriesRegexp: "^foo=bar$,^baz=ding$",
- shouldMatch: true,
- },
- {
- title: "Queries route, bad query",
- route: new(Route).Queries("foo", "bar", "baz", "ding"),
- request: newRequest("GET", "http://localhost?foo=bar&baz=dong"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo=bar,baz=ding",
- queriesRegexp: "^foo=bar$,^baz=ding$",
- shouldMatch: false,
- },
- {
- title: "Queries route with pattern, match",
- route: new(Route).Queries("foo", "{v1}"),
- request: newRequest("GET", "http://localhost?foo=bar"),
- vars: map[string]string{"v1": "bar"},
- host: "",
- path: "",
- query: "foo=bar",
- queriesTemplate: "foo={v1}",
- queriesRegexp: "^foo=(?P<v0>.*)$",
- shouldMatch: true,
- },
- {
- title: "Queries route with multiple patterns, match",
- route: new(Route).Queries("foo", "{v1}", "baz", "{v2}"),
- request: newRequest("GET", "http://localhost?foo=bar&baz=ding"),
- vars: map[string]string{"v1": "bar", "v2": "ding"},
- host: "",
- path: "",
- query: "foo=bar&baz=ding",
- queriesTemplate: "foo={v1},baz={v2}",
- queriesRegexp: "^foo=(?P<v0>.*)$,^baz=(?P<v0>.*)$",
- shouldMatch: true,
- },
- {
- title: "Queries route with regexp pattern, match",
- route: new(Route).Queries("foo", "{v1:[0-9]+}"),
- request: newRequest("GET", "http://localhost?foo=10"),
- vars: map[string]string{"v1": "10"},
- host: "",
- path: "",
- query: "foo=10",
- queriesTemplate: "foo={v1:[0-9]+}",
- queriesRegexp: "^foo=(?P<v0>[0-9]+)$",
- shouldMatch: true,
- },
- {
- title: "Queries route with regexp pattern, regexp does not match",
- route: new(Route).Queries("foo", "{v1:[0-9]+}"),
- request: newRequest("GET", "http://localhost?foo=a"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo={v1:[0-9]+}",
- queriesRegexp: "^foo=(?P<v0>[0-9]+)$",
- shouldMatch: false,
- },
- {
- title: "Queries route with regexp pattern with quantifier, match",
- route: new(Route).Queries("foo", "{v1:[0-9]{1}}"),
- request: newRequest("GET", "http://localhost?foo=1"),
- vars: map[string]string{"v1": "1"},
- host: "",
- path: "",
- query: "foo=1",
- queriesTemplate: "foo={v1:[0-9]{1}}",
- queriesRegexp: "^foo=(?P<v0>[0-9]{1})$",
- shouldMatch: true,
- },
- {
- title: "Queries route with regexp pattern with quantifier, additional variable in query string, match",
- route: new(Route).Queries("foo", "{v1:[0-9]{1}}"),
- request: newRequest("GET", "http://localhost?bar=2&foo=1"),
- vars: map[string]string{"v1": "1"},
- host: "",
- path: "",
- query: "foo=1",
- queriesTemplate: "foo={v1:[0-9]{1}}",
- queriesRegexp: "^foo=(?P<v0>[0-9]{1})$",
- shouldMatch: true,
- },
- {
- title: "Queries route with regexp pattern with quantifier, regexp does not match",
- route: new(Route).Queries("foo", "{v1:[0-9]{1}}"),
- request: newRequest("GET", "http://localhost?foo=12"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo={v1:[0-9]{1}}",
- queriesRegexp: "^foo=(?P<v0>[0-9]{1})$",
- shouldMatch: false,
- },
- {
- title: "Queries route with regexp pattern with quantifier, additional capturing group",
- route: new(Route).Queries("foo", "{v1:[0-9]{1}(?:a|b)}"),
- request: newRequest("GET", "http://localhost?foo=1a"),
- vars: map[string]string{"v1": "1a"},
- host: "",
- path: "",
- query: "foo=1a",
- queriesTemplate: "foo={v1:[0-9]{1}(?:a|b)}",
- queriesRegexp: "^foo=(?P<v0>[0-9]{1}(?:a|b))$",
- shouldMatch: true,
- },
- {
- title: "Queries route with regexp pattern with quantifier, additional variable in query string, regexp does not match",
- route: new(Route).Queries("foo", "{v1:[0-9]{1}}"),
- request: newRequest("GET", "http://localhost?foo=12"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo={v1:[0-9]{1}}",
- queriesRegexp: "^foo=(?P<v0>[0-9]{1})$",
- shouldMatch: false,
- },
- {
- title: "Queries route with hyphenated name, match",
- route: new(Route).Queries("foo", "{v-1}"),
- request: newRequest("GET", "http://localhost?foo=bar"),
- vars: map[string]string{"v-1": "bar"},
- host: "",
- path: "",
- query: "foo=bar",
- queriesTemplate: "foo={v-1}",
- queriesRegexp: "^foo=(?P<v0>.*)$",
- shouldMatch: true,
- },
- {
- title: "Queries route with multiple hyphenated names, match",
- route: new(Route).Queries("foo", "{v-1}", "baz", "{v-2}"),
- request: newRequest("GET", "http://localhost?foo=bar&baz=ding"),
- vars: map[string]string{"v-1": "bar", "v-2": "ding"},
- host: "",
- path: "",
- query: "foo=bar&baz=ding",
- queriesTemplate: "foo={v-1},baz={v-2}",
- queriesRegexp: "^foo=(?P<v0>.*)$,^baz=(?P<v0>.*)$",
- shouldMatch: true,
- },
- {
- title: "Queries route with hyphenate name and pattern, match",
- route: new(Route).Queries("foo", "{v-1:[0-9]+}"),
- request: newRequest("GET", "http://localhost?foo=10"),
- vars: map[string]string{"v-1": "10"},
- host: "",
- path: "",
- query: "foo=10",
- queriesTemplate: "foo={v-1:[0-9]+}",
- queriesRegexp: "^foo=(?P<v0>[0-9]+)$",
- shouldMatch: true,
- },
- {
- title: "Queries route with hyphenated name and pattern with quantifier, additional capturing group",
- route: new(Route).Queries("foo", "{v-1:[0-9]{1}(?:a|b)}"),
- request: newRequest("GET", "http://localhost?foo=1a"),
- vars: map[string]string{"v-1": "1a"},
- host: "",
- path: "",
- query: "foo=1a",
- queriesTemplate: "foo={v-1:[0-9]{1}(?:a|b)}",
- queriesRegexp: "^foo=(?P<v0>[0-9]{1}(?:a|b))$",
- shouldMatch: true,
- },
- {
- title: "Queries route with empty value, should match",
- route: new(Route).Queries("foo", ""),
- request: newRequest("GET", "http://localhost?foo=bar"),
- vars: map[string]string{},
- host: "",
- path: "",
- query: "foo=",
- queriesTemplate: "foo=",
- queriesRegexp: "^foo=.*$",
- shouldMatch: true,
- },
- {
- title: "Queries route with empty value and no parameter in request, should not match",
- route: new(Route).Queries("foo", ""),
- request: newRequest("GET", "http://localhost"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo=",
- queriesRegexp: "^foo=.*$",
- shouldMatch: false,
- },
- {
- title: "Queries route with empty value and empty parameter in request, should match",
- route: new(Route).Queries("foo", ""),
- request: newRequest("GET", "http://localhost?foo="),
- vars: map[string]string{},
- host: "",
- path: "",
- query: "foo=",
- queriesTemplate: "foo=",
- queriesRegexp: "^foo=.*$",
- shouldMatch: true,
- },
- {
- title: "Queries route with overlapping value, should not match",
- route: new(Route).Queries("foo", "bar"),
- request: newRequest("GET", "http://localhost?foo=barfoo"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo=bar",
- queriesRegexp: "^foo=bar$",
- shouldMatch: false,
- },
- {
- title: "Queries route with no parameter in request, should not match",
- route: new(Route).Queries("foo", "{bar}"),
- request: newRequest("GET", "http://localhost"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo={bar}",
- queriesRegexp: "^foo=(?P<v0>.*)$",
- shouldMatch: false,
- },
- {
- title: "Queries route with empty parameter in request, should match",
- route: new(Route).Queries("foo", "{bar}"),
- request: newRequest("GET", "http://localhost?foo="),
- vars: map[string]string{"foo": ""},
- host: "",
- path: "",
- query: "foo=",
- queriesTemplate: "foo={bar}",
- queriesRegexp: "^foo=(?P<v0>.*)$",
- shouldMatch: true,
- },
- {
- title: "Queries route, bad submatch",
- route: new(Route).Queries("foo", "bar", "baz", "ding"),
- request: newRequest("GET", "http://localhost?fffoo=bar&baz=dingggg"),
- vars: map[string]string{},
- host: "",
- path: "",
- queriesTemplate: "foo=bar,baz=ding",
- queriesRegexp: "^foo=bar$,^baz=ding$",
- shouldMatch: false,
- },
- {
- title: "Queries route with pattern, match, escaped value",
- route: new(Route).Queries("foo", "{v1}"),
- request: newRequest("GET", "http://localhost?foo=%25bar%26%20%2F%3D%3F"),
- vars: map[string]string{"v1": "%bar& /=?"},
- host: "",
- path: "",
- query: "foo=%25bar%26+%2F%3D%3F",
- queriesTemplate: "foo={v1}",
- queriesRegexp: "^foo=(?P<v0>.*)$",
- shouldMatch: true,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- testQueriesTemplates(t, test)
- testUseEscapedRoute(t, test)
- testQueriesRegexp(t, test)
- }
-}
-
-func TestSchemes(t *testing.T) {
- tests := []routeTest{
- // Schemes
- {
- title: "Schemes route, default scheme, match http, build http",
- route: new(Route).Host("localhost"),
- request: newRequest("GET", "http://localhost"),
- scheme: "http",
- host: "localhost",
- shouldMatch: true,
- },
- {
- title: "Schemes route, match https, build https",
- route: new(Route).Schemes("https", "ftp").Host("localhost"),
- request: newRequest("GET", "https://localhost"),
- scheme: "https",
- host: "localhost",
- shouldMatch: true,
- },
- {
- title: "Schemes route, match ftp, build https",
- route: new(Route).Schemes("https", "ftp").Host("localhost"),
- request: newRequest("GET", "ftp://localhost"),
- scheme: "https",
- host: "localhost",
- shouldMatch: true,
- },
- {
- title: "Schemes route, match ftp, build ftp",
- route: new(Route).Schemes("ftp", "https").Host("localhost"),
- request: newRequest("GET", "ftp://localhost"),
- scheme: "ftp",
- host: "localhost",
- shouldMatch: true,
- },
- {
- title: "Schemes route, bad scheme",
- route: new(Route).Schemes("https", "ftp").Host("localhost"),
- request: newRequest("GET", "http://localhost"),
- scheme: "https",
- host: "localhost",
- shouldMatch: false,
- },
- }
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- }
-}
-
-func TestMatcherFunc(t *testing.T) {
- m := func(r *http.Request, m *RouteMatch) bool {
- if r.URL.Host == "aaa.bbb.ccc" {
- return true
- }
- return false
- }
-
- tests := []routeTest{
- {
- title: "MatchFunc route, match",
- route: new(Route).MatcherFunc(m),
- request: newRequest("GET", "http://aaa.bbb.ccc"),
- vars: map[string]string{},
- host: "",
- path: "",
- shouldMatch: true,
- },
- {
- title: "MatchFunc route, non-match",
- route: new(Route).MatcherFunc(m),
- request: newRequest("GET", "http://aaa.222.ccc"),
- vars: map[string]string{},
- host: "",
- path: "",
- shouldMatch: false,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- }
-}
-
-func TestBuildVarsFunc(t *testing.T) {
- tests := []routeTest{
- {
- title: "BuildVarsFunc set on route",
- route: new(Route).Path(`/111/{v1:\d}{v2:.*}`).BuildVarsFunc(func(vars map[string]string) map[string]string {
- vars["v1"] = "3"
- vars["v2"] = "a"
- return vars
- }),
- request: newRequest("GET", "http://localhost/111/2"),
- path: "/111/3a",
- pathTemplate: `/111/{v1:\d}{v2:.*}`,
- shouldMatch: true,
- },
- {
- title: "BuildVarsFunc set on route and parent route",
- route: new(Route).PathPrefix(`/{v1:\d}`).BuildVarsFunc(func(vars map[string]string) map[string]string {
- vars["v1"] = "2"
- return vars
- }).Subrouter().Path(`/{v2:\w}`).BuildVarsFunc(func(vars map[string]string) map[string]string {
- vars["v2"] = "b"
- return vars
- }),
- request: newRequest("GET", "http://localhost/1/a"),
- path: "/2/b",
- pathTemplate: `/{v1:\d}/{v2:\w}`,
- shouldMatch: true,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- }
-}
-
-func TestSubRouter(t *testing.T) {
- subrouter1 := new(Route).Host("{v1:[a-z]+}.google.com").Subrouter()
- subrouter2 := new(Route).PathPrefix("/foo/{v1}").Subrouter()
- subrouter3 := new(Route).PathPrefix("/foo").Subrouter()
- subrouter4 := new(Route).PathPrefix("/foo/bar").Subrouter()
- subrouter5 := new(Route).PathPrefix("/{category}").Subrouter()
-
- tests := []routeTest{
- {
- route: subrouter1.Path("/{v2:[a-z]+}"),
- request: newRequest("GET", "http://aaa.google.com/bbb"),
- vars: map[string]string{"v1": "aaa", "v2": "bbb"},
- host: "aaa.google.com",
- path: "/bbb",
- pathTemplate: `/{v2:[a-z]+}`,
- hostTemplate: `{v1:[a-z]+}.google.com`,
- shouldMatch: true,
- },
- {
- route: subrouter1.Path("/{v2:[a-z]+}"),
- request: newRequest("GET", "http://111.google.com/111"),
- vars: map[string]string{"v1": "aaa", "v2": "bbb"},
- host: "aaa.google.com",
- path: "/bbb",
- pathTemplate: `/{v2:[a-z]+}`,
- hostTemplate: `{v1:[a-z]+}.google.com`,
- shouldMatch: false,
- },
- {
- route: subrouter2.Path("/baz/{v2}"),
- request: newRequest("GET", "http://localhost/foo/bar/baz/ding"),
- vars: map[string]string{"v1": "bar", "v2": "ding"},
- host: "",
- path: "/foo/bar/baz/ding",
- pathTemplate: `/foo/{v1}/baz/{v2}`,
- shouldMatch: true,
- },
- {
- route: subrouter2.Path("/baz/{v2}"),
- request: newRequest("GET", "http://localhost/foo/bar"),
- vars: map[string]string{"v1": "bar", "v2": "ding"},
- host: "",
- path: "/foo/bar/baz/ding",
- pathTemplate: `/foo/{v1}/baz/{v2}`,
- shouldMatch: false,
- },
- {
- route: subrouter3.Path("/"),
- request: newRequest("GET", "http://localhost/foo/"),
- vars: map[string]string{},
- host: "",
- path: "/foo/",
- pathTemplate: `/foo/`,
- shouldMatch: true,
- },
- {
- route: subrouter3.Path(""),
- request: newRequest("GET", "http://localhost/foo"),
- vars: map[string]string{},
- host: "",
- path: "/foo",
- pathTemplate: `/foo`,
- shouldMatch: true,
- },
-
- {
- route: subrouter4.Path("/"),
- request: newRequest("GET", "http://localhost/foo/bar/"),
- vars: map[string]string{},
- host: "",
- path: "/foo/bar/",
- pathTemplate: `/foo/bar/`,
- shouldMatch: true,
- },
- {
- route: subrouter4.Path(""),
- request: newRequest("GET", "http://localhost/foo/bar"),
- vars: map[string]string{},
- host: "",
- path: "/foo/bar",
- pathTemplate: `/foo/bar`,
- shouldMatch: true,
- },
- {
- route: subrouter5.Path("/"),
- request: newRequest("GET", "http://localhost/baz/"),
- vars: map[string]string{"category": "baz"},
- host: "",
- path: "/baz/",
- pathTemplate: `/{category}/`,
- shouldMatch: true,
- },
- {
- route: subrouter5.Path(""),
- request: newRequest("GET", "http://localhost/baz"),
- vars: map[string]string{"category": "baz"},
- host: "",
- path: "/baz",
- pathTemplate: `/{category}`,
- shouldMatch: true,
- },
- {
- title: "Build with scheme on parent router",
- route: new(Route).Schemes("ftp").Host("google.com").Subrouter().Path("/"),
- request: newRequest("GET", "ftp://google.com/"),
- scheme: "ftp",
- host: "google.com",
- path: "/",
- pathTemplate: `/`,
- hostTemplate: `google.com`,
- shouldMatch: true,
- },
- {
- title: "Prefer scheme on child route when building URLs",
- route: new(Route).Schemes("https", "ftp").Host("google.com").Subrouter().Schemes("ftp").Path("/"),
- request: newRequest("GET", "ftp://google.com/"),
- scheme: "ftp",
- host: "google.com",
- path: "/",
- pathTemplate: `/`,
- hostTemplate: `google.com`,
- shouldMatch: true,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- testUseEscapedRoute(t, test)
- }
-}
-
-func TestNamedRoutes(t *testing.T) {
- r1 := NewRouter()
- r1.NewRoute().Name("a")
- r1.NewRoute().Name("b")
- r1.NewRoute().Name("c")
-
- r2 := r1.NewRoute().Subrouter()
- r2.NewRoute().Name("d")
- r2.NewRoute().Name("e")
- r2.NewRoute().Name("f")
-
- r3 := r2.NewRoute().Subrouter()
- r3.NewRoute().Name("g")
- r3.NewRoute().Name("h")
- r3.NewRoute().Name("i")
-
- if r1.namedRoutes == nil || len(r1.namedRoutes) != 9 {
- t.Errorf("Expected 9 named routes, got %v", r1.namedRoutes)
- } else if r1.Get("i") == nil {
- t.Errorf("Subroute name not registered")
- }
-}
-
-func TestStrictSlash(t *testing.T) {
- r := NewRouter()
- r.StrictSlash(true)
-
- tests := []routeTest{
- {
- title: "Redirect path without slash",
- route: r.NewRoute().Path("/111/"),
- request: newRequest("GET", "http://localhost/111"),
- vars: map[string]string{},
- host: "",
- path: "/111/",
- shouldMatch: true,
- shouldRedirect: true,
- },
- {
- title: "Do not redirect path with slash",
- route: r.NewRoute().Path("/111/"),
- request: newRequest("GET", "http://localhost/111/"),
- vars: map[string]string{},
- host: "",
- path: "/111/",
- shouldMatch: true,
- shouldRedirect: false,
- },
- {
- title: "Redirect path with slash",
- route: r.NewRoute().Path("/111"),
- request: newRequest("GET", "http://localhost/111/"),
- vars: map[string]string{},
- host: "",
- path: "/111",
- shouldMatch: true,
- shouldRedirect: true,
- },
- {
- title: "Do not redirect path without slash",
- route: r.NewRoute().Path("/111"),
- request: newRequest("GET", "http://localhost/111"),
- vars: map[string]string{},
- host: "",
- path: "/111",
- shouldMatch: true,
- shouldRedirect: false,
- },
- {
- title: "Propagate StrictSlash to subrouters",
- route: r.NewRoute().PathPrefix("/static/").Subrouter().Path("/images/"),
- request: newRequest("GET", "http://localhost/static/images"),
- vars: map[string]string{},
- host: "",
- path: "/static/images/",
- shouldMatch: true,
- shouldRedirect: true,
- },
- {
- title: "Ignore StrictSlash for path prefix",
- route: r.NewRoute().PathPrefix("/static/"),
- request: newRequest("GET", "http://localhost/static/logo.png"),
- vars: map[string]string{},
- host: "",
- path: "/static/",
- shouldMatch: true,
- shouldRedirect: false,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- testUseEscapedRoute(t, test)
- }
-}
-
-func TestUseEncodedPath(t *testing.T) {
- r := NewRouter()
- r.UseEncodedPath()
-
- tests := []routeTest{
- {
- title: "Router with useEncodedPath, URL with encoded slash does match",
- route: r.NewRoute().Path("/v1/{v1}/v2"),
- request: newRequest("GET", "http://localhost/v1/1%2F2/v2"),
- vars: map[string]string{"v1": "1%2F2"},
- host: "",
- path: "/v1/1%2F2/v2",
- pathTemplate: `/v1/{v1}/v2`,
- shouldMatch: true,
- },
- {
- title: "Router with useEncodedPath, URL with encoded slash doesn't match",
- route: r.NewRoute().Path("/v1/1/2/v2"),
- request: newRequest("GET", "http://localhost/v1/1%2F2/v2"),
- vars: map[string]string{"v1": "1%2F2"},
- host: "",
- path: "/v1/1%2F2/v2",
- pathTemplate: `/v1/1/2/v2`,
- shouldMatch: false,
- },
- }
-
- for _, test := range tests {
- testRoute(t, test)
- testTemplate(t, test)
- }
-}
-
-func TestWalkSingleDepth(t *testing.T) {
- r0 := NewRouter()
- r1 := NewRouter()
- r2 := NewRouter()
-
- r0.Path("/g")
- r0.Path("/o")
- r0.Path("/d").Handler(r1)
- r0.Path("/r").Handler(r2)
- r0.Path("/a")
-
- r1.Path("/z")
- r1.Path("/i")
- r1.Path("/l")
- r1.Path("/l")
-
- r2.Path("/i")
- r2.Path("/l")
- r2.Path("/l")
-
- paths := []string{"g", "o", "r", "i", "l", "l", "a"}
- depths := []int{0, 0, 0, 1, 1, 1, 0}
- i := 0
- err := r0.Walk(func(route *Route, router *Router, ancestors []*Route) error {
- matcher := route.matchers[0].(*routeRegexp)
- if matcher.template == "/d" {
- return SkipRouter
- }
- if len(ancestors) != depths[i] {
- t.Errorf(`Expected depth of %d at i = %d; got "%d"`, depths[i], i, len(ancestors))
- }
- if matcher.template != "/"+paths[i] {
- t.Errorf(`Expected "/%s" at i = %d; got "%s"`, paths[i], i, matcher.template)
- }
- i++
- return nil
- })
- if err != nil {
- panic(err)
- }
- if i != len(paths) {
- t.Errorf("Expected %d routes, found %d", len(paths), i)
- }
-}
-
-func TestWalkNested(t *testing.T) {
- router := NewRouter()
-
- g := router.Path("/g").Subrouter()
- o := g.PathPrefix("/o").Subrouter()
- r := o.PathPrefix("/r").Subrouter()
- i := r.PathPrefix("/i").Subrouter()
- l1 := i.PathPrefix("/l").Subrouter()
- l2 := l1.PathPrefix("/l").Subrouter()
- l2.Path("/a")
-
- testCases := []struct {
- path string
- ancestors []*Route
- }{
- {"/g", []*Route{}},
- {"/g/o", []*Route{g.parent.(*Route)}},
- {"/g/o/r", []*Route{g.parent.(*Route), o.parent.(*Route)}},
- {"/g/o/r/i", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route)}},
- {"/g/o/r/i/l", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route), i.parent.(*Route)}},
- {"/g/o/r/i/l/l", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route), i.parent.(*Route), l1.parent.(*Route)}},
- {"/g/o/r/i/l/l/a", []*Route{g.parent.(*Route), o.parent.(*Route), r.parent.(*Route), i.parent.(*Route), l1.parent.(*Route), l2.parent.(*Route)}},
- }
-
- idx := 0
- err := router.Walk(func(route *Route, router *Router, ancestors []*Route) error {
- path := testCases[idx].path
- tpl := route.regexp.path.template
- if tpl != path {
- t.Errorf(`Expected %s got %s`, path, tpl)
- }
- currWantAncestors := testCases[idx].ancestors
- if !reflect.DeepEqual(currWantAncestors, ancestors) {
- t.Errorf(`Expected %+v got %+v`, currWantAncestors, ancestors)
- }
- idx++
- return nil
- })
- if err != nil {
- panic(err)
- }
- if idx != len(testCases) {
- t.Errorf("Expected %d routes, found %d", len(testCases), idx)
- }
-}
-
-func TestWalkSubrouters(t *testing.T) {
- router := NewRouter()
-
- g := router.Path("/g").Subrouter()
- o := g.PathPrefix("/o").Subrouter()
- o.Methods("GET")
- o.Methods("PUT")
-
- // all 4 routes should be matched, but final 2 routes do not have path templates
- paths := []string{"/g", "/g/o", "", ""}
- idx := 0
- err := router.Walk(func(route *Route, router *Router, ancestors []*Route) error {
- path := paths[idx]
- tpl, _ := route.GetPathTemplate()
- if tpl != path {
- t.Errorf(`Expected %s got %s`, path, tpl)
- }
- idx++
- return nil
- })
- if err != nil {
- panic(err)
- }
- if idx != len(paths) {
- t.Errorf("Expected %d routes, found %d", len(paths), idx)
- }
-}
-
-func TestWalkErrorRoute(t *testing.T) {
- router := NewRouter()
- router.Path("/g")
- expectedError := errors.New("error")
- err := router.Walk(func(route *Route, router *Router, ancestors []*Route) error {
- return expectedError
- })
- if err != expectedError {
- t.Errorf("Expected %v routes, found %v", expectedError, err)
- }
-}
-
-func TestWalkErrorMatcher(t *testing.T) {
- router := NewRouter()
- expectedError := router.Path("/g").Subrouter().Path("").GetError()
- err := router.Walk(func(route *Route, router *Router, ancestors []*Route) error {
- return route.GetError()
- })
- if err != expectedError {
- t.Errorf("Expected %v routes, found %v", expectedError, err)
- }
-}
-
-func TestWalkErrorHandler(t *testing.T) {
- handler := NewRouter()
- expectedError := handler.Path("/path").Subrouter().Path("").GetError()
- router := NewRouter()
- router.Path("/g").Handler(handler)
- err := router.Walk(func(route *Route, router *Router, ancestors []*Route) error {
- return route.GetError()
- })
- if err != expectedError {
- t.Errorf("Expected %v routes, found %v", expectedError, err)
- }
-}
-
-func TestSubrouterErrorHandling(t *testing.T) {
- superRouterCalled := false
- subRouterCalled := false
-
- router := NewRouter()
- router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- superRouterCalled = true
- })
- subRouter := router.PathPrefix("/bign8").Subrouter()
- subRouter.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- subRouterCalled = true
- })
-
- req, _ := http.NewRequest("GET", "http://localhost/bign8/was/here", nil)
- router.ServeHTTP(NewRecorder(), req)
-
- if superRouterCalled {
- t.Error("Super router 404 handler called when sub-router 404 handler is available.")
- }
- if !subRouterCalled {
- t.Error("Sub-router 404 handler was not called.")
- }
-}
-
-// See: https://github.com/gorilla/mux/issues/200
-func TestPanicOnCapturingGroups(t *testing.T) {
- defer func() {
- if recover() == nil {
- t.Errorf("(Test that capturing groups now fail fast) Expected panic, however test completed successfully.\n")
- }
- }()
- NewRouter().NewRoute().Path("/{type:(promo|special)}/{promoId}.json")
-}
-
-// ----------------------------------------------------------------------------
-// Helpers
-// ----------------------------------------------------------------------------
-
-func getRouteTemplate(route *Route) string {
- host, err := route.GetHostTemplate()
- if err != nil {
- host = "none"
- }
- path, err := route.GetPathTemplate()
- if err != nil {
- path = "none"
- }
- return fmt.Sprintf("Host: %v, Path: %v", host, path)
-}
-
-func testRoute(t *testing.T, test routeTest) {
- request := test.request
- route := test.route
- vars := test.vars
- shouldMatch := test.shouldMatch
- query := test.query
- shouldRedirect := test.shouldRedirect
- uri := url.URL{
- Scheme: test.scheme,
- Host: test.host,
- Path: test.path,
- }
- if uri.Scheme == "" {
- uri.Scheme = "http"
- }
-
- var match RouteMatch
- ok := route.Match(request, &match)
- if ok != shouldMatch {
- msg := "Should match"
- if !shouldMatch {
- msg = "Should not match"
- }
- t.Errorf("(%v) %v:\nRoute: %#v\nRequest: %#v\nVars: %v\n", test.title, msg, route, request, vars)
- return
- }
- if shouldMatch {
- if vars != nil && !stringMapEqual(vars, match.Vars) {
- t.Errorf("(%v) Vars not equal: expected %v, got %v", test.title, vars, match.Vars)
- return
- }
- if test.scheme != "" {
- u, err := route.URL(mapToPairs(match.Vars)...)
- if err != nil {
- t.Fatalf("(%v) URL error: %v -- %v", test.title, err, getRouteTemplate(route))
- }
- if uri.Scheme != u.Scheme {
- t.Errorf("(%v) URLScheme not equal: expected %v, got %v", test.title, uri.Scheme, u.Scheme)
- return
- }
- }
- if test.host != "" {
- u, err := test.route.URLHost(mapToPairs(match.Vars)...)
- if err != nil {
- t.Fatalf("(%v) URLHost error: %v -- %v", test.title, err, getRouteTemplate(route))
- }
- if uri.Scheme != u.Scheme {
- t.Errorf("(%v) URLHost scheme not equal: expected %v, got %v -- %v", test.title, uri.Scheme, u.Scheme, getRouteTemplate(route))
- return
- }
- if uri.Host != u.Host {
- t.Errorf("(%v) URLHost host not equal: expected %v, got %v -- %v", test.title, uri.Host, u.Host, getRouteTemplate(route))
- return
- }
- }
- if test.path != "" {
- u, err := route.URLPath(mapToPairs(match.Vars)...)
- if err != nil {
- t.Fatalf("(%v) URLPath error: %v -- %v", test.title, err, getRouteTemplate(route))
- }
- if uri.Path != u.Path {
- t.Errorf("(%v) URLPath not equal: expected %v, got %v -- %v", test.title, uri.Path, u.Path, getRouteTemplate(route))
- return
- }
- }
- if test.host != "" && test.path != "" {
- u, err := route.URL(mapToPairs(match.Vars)...)
- if err != nil {
- t.Fatalf("(%v) URL error: %v -- %v", test.title, err, getRouteTemplate(route))
- }
- if expected, got := uri.String(), u.String(); expected != got {
- t.Errorf("(%v) URL not equal: expected %v, got %v -- %v", test.title, expected, got, getRouteTemplate(route))
- return
- }
- }
- if query != "" {
- u, _ := route.URL(mapToPairs(match.Vars)...)
- if query != u.RawQuery {
- t.Errorf("(%v) URL query not equal: expected %v, got %v", test.title, query, u.RawQuery)
- return
- }
- }
- if shouldRedirect && match.Handler == nil {
- t.Errorf("(%v) Did not redirect", test.title)
- return
- }
- if !shouldRedirect && match.Handler != nil {
- t.Errorf("(%v) Unexpected redirect", test.title)
- return
- }
- }
-}
-
-func testUseEscapedRoute(t *testing.T, test routeTest) {
- test.route.useEncodedPath = true
- testRoute(t, test)
-}
-
-func testTemplate(t *testing.T, test routeTest) {
- route := test.route
- pathTemplate := test.pathTemplate
- if len(pathTemplate) == 0 {
- pathTemplate = test.path
- }
- hostTemplate := test.hostTemplate
- if len(hostTemplate) == 0 {
- hostTemplate = test.host
- }
-
- routePathTemplate, pathErr := route.GetPathTemplate()
- if pathErr == nil && routePathTemplate != pathTemplate {
- t.Errorf("(%v) GetPathTemplate not equal: expected %v, got %v", test.title, pathTemplate, routePathTemplate)
- }
-
- routeHostTemplate, hostErr := route.GetHostTemplate()
- if hostErr == nil && routeHostTemplate != hostTemplate {
- t.Errorf("(%v) GetHostTemplate not equal: expected %v, got %v", test.title, hostTemplate, routeHostTemplate)
- }
-}
-
-func testMethods(t *testing.T, test routeTest) {
- route := test.route
- methods, _ := route.GetMethods()
- if strings.Join(methods, ",") != strings.Join(test.methods, ",") {
- t.Errorf("(%v) GetMethods not equal: expected %v, got %v", test.title, test.methods, methods)
- }
-}
-
-func testRegexp(t *testing.T, test routeTest) {
- route := test.route
- routePathRegexp, regexpErr := route.GetPathRegexp()
- if test.pathRegexp != "" && regexpErr == nil && routePathRegexp != test.pathRegexp {
- t.Errorf("(%v) GetPathRegexp not equal: expected %v, got %v", test.title, test.pathRegexp, routePathRegexp)
- }
-}
-
-func testQueriesRegexp(t *testing.T, test routeTest) {
- route := test.route
- queries, queriesErr := route.GetQueriesRegexp()
- gotQueries := strings.Join(queries, ",")
- if test.queriesRegexp != "" && queriesErr == nil && gotQueries != test.queriesRegexp {
- t.Errorf("(%v) GetQueriesRegexp not equal: expected %v, got %v", test.title, test.queriesRegexp, gotQueries)
- }
-}
-
-func testQueriesTemplates(t *testing.T, test routeTest) {
- route := test.route
- queries, queriesErr := route.GetQueriesTemplates()
- gotQueries := strings.Join(queries, ",")
- if test.queriesTemplate != "" && queriesErr == nil && gotQueries != test.queriesTemplate {
- t.Errorf("(%v) GetQueriesTemplates not equal: expected %v, got %v", test.title, test.queriesTemplate, gotQueries)
- }
-}
-
-type TestA301ResponseWriter struct {
- hh http.Header
- status int
-}
-
-func (ho *TestA301ResponseWriter) Header() http.Header {
- return http.Header(ho.hh)
-}
-
-func (ho *TestA301ResponseWriter) Write(b []byte) (int, error) {
- return 0, nil
-}
-
-func (ho *TestA301ResponseWriter) WriteHeader(code int) {
- ho.status = code
-}
-
-func Test301Redirect(t *testing.T) {
- m := make(http.Header)
-
- func1 := func(w http.ResponseWriter, r *http.Request) {}
- func2 := func(w http.ResponseWriter, r *http.Request) {}
-
- r := NewRouter()
- r.HandleFunc("/api/", func2).Name("func2")
- r.HandleFunc("/", func1).Name("func1")
-
- req, _ := http.NewRequest("GET", "http://localhost//api/?abc=def", nil)
-
- res := TestA301ResponseWriter{
- hh: m,
- status: 0,
- }
- r.ServeHTTP(&res, req)
-
- if "http://localhost/api/?abc=def" != res.hh["Location"][0] {
- t.Errorf("Should have complete URL with query string")
- }
-}
-
-func TestSkipClean(t *testing.T) {
- func1 := func(w http.ResponseWriter, r *http.Request) {}
- func2 := func(w http.ResponseWriter, r *http.Request) {}
-
- r := NewRouter()
- r.SkipClean(true)
- r.HandleFunc("/api/", func2).Name("func2")
- r.HandleFunc("/", func1).Name("func1")
-
- req, _ := http.NewRequest("GET", "http://localhost//api/?abc=def", nil)
- res := NewRecorder()
- r.ServeHTTP(res, req)
-
- if len(res.HeaderMap["Location"]) != 0 {
- t.Errorf("Shouldn't redirect since skip clean is disabled")
- }
-}
-
-// https://plus.google.com/101022900381697718949/posts/eWy6DjFJ6uW
-func TestSubrouterHeader(t *testing.T) {
- expected := "func1 response"
- func1 := func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprint(w, expected)
- }
- func2 := func(http.ResponseWriter, *http.Request) {}
-
- r := NewRouter()
- s := r.Headers("SomeSpecialHeader", "").Subrouter()
- s.HandleFunc("/", func1).Name("func1")
- r.HandleFunc("/", func2).Name("func2")
-
- req, _ := http.NewRequest("GET", "http://localhost/", nil)
- req.Header.Add("SomeSpecialHeader", "foo")
- match := new(RouteMatch)
- matched := r.Match(req, match)
- if !matched {
- t.Errorf("Should match request")
- }
- if match.Route.GetName() != "func1" {
- t.Errorf("Expecting func1 handler, got %s", match.Route.GetName())
- }
- resp := NewRecorder()
- match.Handler.ServeHTTP(resp, req)
- if resp.Body.String() != expected {
- t.Errorf("Expecting %q", expected)
- }
-}
-
-func TestNoMatchMethodErrorHandler(t *testing.T) {
- func1 := func(w http.ResponseWriter, r *http.Request) {}
-
- r := NewRouter()
- r.HandleFunc("/", func1).Methods("GET", "POST")
-
- req, _ := http.NewRequest("PUT", "http://localhost/", nil)
- match := new(RouteMatch)
- matched := r.Match(req, match)
-
- if matched {
- t.Error("Should not have matched route for methods")
- }
-
- if match.MatchErr != ErrMethodMismatch {
- t.Error("Should get ErrMethodMismatch error")
- }
-
- resp := NewRecorder()
- r.ServeHTTP(resp, req)
- if resp.Code != 405 {
- t.Errorf("Expecting code %v", 405)
- }
-
- // Add matching route
- r.HandleFunc("/", func1).Methods("PUT")
-
- match = new(RouteMatch)
- matched = r.Match(req, match)
-
- if !matched {
- t.Error("Should have matched route for methods")
- }
-
- if match.MatchErr != nil {
- t.Error("Should not have any matching error. Found:", match.MatchErr)
- }
-}
-
-func TestErrMatchNotFound(t *testing.T) {
- emptyHandler := func(w http.ResponseWriter, r *http.Request) {}
-
- r := NewRouter()
- r.HandleFunc("/", emptyHandler)
- s := r.PathPrefix("/sub/").Subrouter()
- s.HandleFunc("/", emptyHandler)
-
- // Regular 404 not found
- req, _ := http.NewRequest("GET", "/sub/whatever", nil)
- match := new(RouteMatch)
- matched := r.Match(req, match)
-
- if matched {
- t.Errorf("Subrouter should not have matched that, got %v", match.Route)
- }
- // Even without a custom handler, MatchErr is set to ErrNotFound
- if match.MatchErr != ErrNotFound {
- t.Errorf("Expected ErrNotFound MatchErr, but was %v", match.MatchErr)
- }
-
- // Now lets add a 404 handler to subrouter
- s.NotFoundHandler = http.NotFoundHandler()
- req, _ = http.NewRequest("GET", "/sub/whatever", nil)
-
- // Test the subrouter first
- match = new(RouteMatch)
- matched = s.Match(req, match)
- // Now we should get a match
- if !matched {
- t.Errorf("Subrouter should have matched %s", req.RequestURI)
- }
- // But MatchErr should be set to ErrNotFound anyway
- if match.MatchErr != ErrNotFound {
- t.Errorf("Expected ErrNotFound MatchErr, but was %v", match.MatchErr)
- }
-
- // Now test the parent (MatchErr should propagate)
- match = new(RouteMatch)
- matched = r.Match(req, match)
-
- // Now we should get a match
- if !matched {
- t.Errorf("Router should have matched %s via subrouter", req.RequestURI)
- }
- // But MatchErr should be set to ErrNotFound anyway
- if match.MatchErr != ErrNotFound {
- t.Errorf("Expected ErrNotFound MatchErr, but was %v", match.MatchErr)
- }
-}
-
-// methodsSubrouterTest models the data necessary for testing handler
-// matching for subrouters created after HTTP methods matcher registration.
-type methodsSubrouterTest struct {
- title string
- wantCode int
- router *Router
- // method is the input into the request and expected response
- method string
- // input request path
- path string
- // redirectTo is the expected location path for strict-slash matches
- redirectTo string
-}
-
-// methodHandler writes the method string in response.
-func methodHandler(method string) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte(method))
- }
-}
-
-// TestMethodsSubrouterCatchall matches handlers for subrouters where a
-// catchall handler is set for a mis-matching method.
-func TestMethodsSubrouterCatchall(t *testing.T) {
- t.Parallel()
-
- router := NewRouter()
- router.Methods("PATCH").Subrouter().PathPrefix("/").HandlerFunc(methodHandler("PUT"))
- router.Methods("GET").Subrouter().HandleFunc("/foo", methodHandler("GET"))
- router.Methods("POST").Subrouter().HandleFunc("/foo", methodHandler("POST"))
- router.Methods("DELETE").Subrouter().HandleFunc("/foo", methodHandler("DELETE"))
-
- tests := []methodsSubrouterTest{
- {
- title: "match GET handler",
- router: router,
- path: "http://localhost/foo",
- method: "GET",
- wantCode: http.StatusOK,
- },
- {
- title: "match POST handler",
- router: router,
- method: "POST",
- path: "http://localhost/foo",
- wantCode: http.StatusOK,
- },
- {
- title: "match DELETE handler",
- router: router,
- method: "DELETE",
- path: "http://localhost/foo",
- wantCode: http.StatusOK,
- },
- {
- title: "disallow PUT method",
- router: router,
- method: "PUT",
- path: "http://localhost/foo",
- wantCode: http.StatusMethodNotAllowed,
- },
- }
-
- for _, test := range tests {
- testMethodsSubrouter(t, test)
- }
-}
-
-// TestMethodsSubrouterStrictSlash matches handlers on subrouters with
-// strict-slash matchers.
-func TestMethodsSubrouterStrictSlash(t *testing.T) {
- t.Parallel()
-
- router := NewRouter()
- sub := router.PathPrefix("/").Subrouter()
- sub.StrictSlash(true).Path("/foo").Methods("GET").Subrouter().HandleFunc("", methodHandler("GET"))
- sub.StrictSlash(true).Path("/foo/").Methods("PUT").Subrouter().HandleFunc("/", methodHandler("PUT"))
- sub.StrictSlash(true).Path("/foo/").Methods("POST").Subrouter().HandleFunc("/", methodHandler("POST"))
-
- tests := []methodsSubrouterTest{
- {
- title: "match POST handler",
- router: router,
- method: "POST",
- path: "http://localhost/foo/",
- wantCode: http.StatusOK,
- },
- {
- title: "match GET handler",
- router: router,
- method: "GET",
- path: "http://localhost/foo",
- wantCode: http.StatusOK,
- },
- {
- title: "match POST handler, redirect strict-slash",
- router: router,
- method: "POST",
- path: "http://localhost/foo",
- redirectTo: "http://localhost/foo/",
- wantCode: http.StatusMovedPermanently,
- },
- {
- title: "match GET handler, redirect strict-slash",
- router: router,
- method: "GET",
- path: "http://localhost/foo/",
- redirectTo: "http://localhost/foo",
- wantCode: http.StatusMovedPermanently,
- },
- {
- title: "disallow DELETE method",
- router: router,
- method: "DELETE",
- path: "http://localhost/foo",
- wantCode: http.StatusMethodNotAllowed,
- },
- }
-
- for _, test := range tests {
- testMethodsSubrouter(t, test)
- }
-}
-
-// TestMethodsSubrouterPathPrefix matches handlers on subrouters created
-// on a router with a path prefix matcher and method matcher.
-func TestMethodsSubrouterPathPrefix(t *testing.T) {
- t.Parallel()
-
- router := NewRouter()
- router.PathPrefix("/1").Methods("POST").Subrouter().HandleFunc("/2", methodHandler("POST"))
- router.PathPrefix("/1").Methods("DELETE").Subrouter().HandleFunc("/2", methodHandler("DELETE"))
- router.PathPrefix("/1").Methods("PUT").Subrouter().HandleFunc("/2", methodHandler("PUT"))
- router.PathPrefix("/1").Methods("POST").Subrouter().HandleFunc("/2", methodHandler("POST2"))
-
- tests := []methodsSubrouterTest{
- {
- title: "match first POST handler",
- router: router,
- method: "POST",
- path: "http://localhost/1/2",
- wantCode: http.StatusOK,
- },
- {
- title: "match DELETE handler",
- router: router,
- method: "DELETE",
- path: "http://localhost/1/2",
- wantCode: http.StatusOK,
- },
- {
- title: "match PUT handler",
- router: router,
- method: "PUT",
- path: "http://localhost/1/2",
- wantCode: http.StatusOK,
- },
- {
- title: "disallow PATCH method",
- router: router,
- method: "PATCH",
- path: "http://localhost/1/2",
- wantCode: http.StatusMethodNotAllowed,
- },
- }
-
- for _, test := range tests {
- testMethodsSubrouter(t, test)
- }
-}
-
-// TestMethodsSubrouterSubrouter matches handlers on subrouters produced
-// from method matchers registered on a root subrouter.
-func TestMethodsSubrouterSubrouter(t *testing.T) {
- t.Parallel()
-
- router := NewRouter()
- sub := router.PathPrefix("/1").Subrouter()
- sub.Methods("POST").Subrouter().HandleFunc("/2", methodHandler("POST"))
- sub.Methods("GET").Subrouter().HandleFunc("/2", methodHandler("GET"))
- sub.Methods("PATCH").Subrouter().HandleFunc("/2", methodHandler("PATCH"))
- sub.HandleFunc("/2", methodHandler("PUT")).Subrouter().Methods("PUT")
- sub.HandleFunc("/2", methodHandler("POST2")).Subrouter().Methods("POST")
-
- tests := []methodsSubrouterTest{
- {
- title: "match first POST handler",
- router: router,
- method: "POST",
- path: "http://localhost/1/2",
- wantCode: http.StatusOK,
- },
- {
- title: "match GET handler",
- router: router,
- method: "GET",
- path: "http://localhost/1/2",
- wantCode: http.StatusOK,
- },
- {
- title: "match PATCH handler",
- router: router,
- method: "PATCH",
- path: "http://localhost/1/2",
- wantCode: http.StatusOK,
- },
- {
- title: "match PUT handler",
- router: router,
- method: "PUT",
- path: "http://localhost/1/2",
- wantCode: http.StatusOK,
- },
- {
- title: "disallow DELETE method",
- router: router,
- method: "DELETE",
- path: "http://localhost/1/2",
- wantCode: http.StatusMethodNotAllowed,
- },
- }
-
- for _, test := range tests {
- testMethodsSubrouter(t, test)
- }
-}
-
-// TestMethodsSubrouterPathVariable matches handlers on matching paths
-// with path variables in them.
-func TestMethodsSubrouterPathVariable(t *testing.T) {
- t.Parallel()
-
- router := NewRouter()
- router.Methods("GET").Subrouter().HandleFunc("/foo", methodHandler("GET"))
- router.Methods("POST").Subrouter().HandleFunc("/{any}", methodHandler("POST"))
- router.Methods("DELETE").Subrouter().HandleFunc("/1/{any}", methodHandler("DELETE"))
- router.Methods("PUT").Subrouter().HandleFunc("/1/{any}", methodHandler("PUT"))
-
- tests := []methodsSubrouterTest{
- {
- title: "match GET handler",
- router: router,
- method: "GET",
- path: "http://localhost/foo",
- wantCode: http.StatusOK,
- },
- {
- title: "match POST handler",
- router: router,
- method: "POST",
- path: "http://localhost/foo",
- wantCode: http.StatusOK,
- },
- {
- title: "match DELETE handler",
- router: router,
- method: "DELETE",
- path: "http://localhost/1/foo",
- wantCode: http.StatusOK,
- },
- {
- title: "match PUT handler",
- router: router,
- method: "PUT",
- path: "http://localhost/1/foo",
- wantCode: http.StatusOK,
- },
- {
- title: "disallow PATCH method",
- router: router,
- method: "PATCH",
- path: "http://localhost/1/foo",
- wantCode: http.StatusMethodNotAllowed,
- },
- }
-
- for _, test := range tests {
- testMethodsSubrouter(t, test)
- }
-}
-
-// testMethodsSubrouter runs an individual methodsSubrouterTest.
-func testMethodsSubrouter(t *testing.T, test methodsSubrouterTest) {
- // Execute request
- req, _ := http.NewRequest(test.method, test.path, nil)
- resp := NewRecorder()
- test.router.ServeHTTP(resp, req)
-
- switch test.wantCode {
- case http.StatusMethodNotAllowed:
- if resp.Code != http.StatusMethodNotAllowed {
- t.Errorf(`(%s) Expected "405 Method Not Allowed", but got %d code`, test.title, resp.Code)
- } else if matchedMethod := resp.Body.String(); matchedMethod != "" {
- t.Errorf(`(%s) Expected "405 Method Not Allowed", but %q handler was called`, test.title, matchedMethod)
- }
-
- case http.StatusMovedPermanently:
- if gotLocation := resp.HeaderMap.Get("Location"); gotLocation != test.redirectTo {
- t.Errorf("(%s) Expected %q route-match to redirect to %q, but got %q", test.title, test.method, test.redirectTo, gotLocation)
- }
-
- case http.StatusOK:
- if matchedMethod := resp.Body.String(); matchedMethod != test.method {
- t.Errorf("(%s) Expected %q handler to be called, but %q handler was called", test.title, test.method, matchedMethod)
- }
-
- default:
- expectedCodes := []int{http.StatusMethodNotAllowed, http.StatusMovedPermanently, http.StatusOK}
- t.Errorf("(%s) Expected wantCode to be one of: %v, but got %d", test.title, expectedCodes, test.wantCode)
- }
-}
-
-// mapToPairs converts a string map to a slice of string pairs
-func mapToPairs(m map[string]string) []string {
- var i int
- p := make([]string, len(m)*2)
- for k, v := range m {
- p[i] = k
- p[i+1] = v
- i += 2
- }
- return p
-}
-
-// stringMapEqual checks the equality of two string maps
-func stringMapEqual(m1, m2 map[string]string) bool {
- nil1 := m1 == nil
- nil2 := m2 == nil
- if nil1 != nil2 || len(m1) != len(m2) {
- return false
- }
- for k, v := range m1 {
- if v != m2[k] {
- return false
- }
- }
- return true
-}
-
-// newRequest is a helper function to create a new request with a method and url.
-// The request returned is a 'server' request as opposed to a 'client' one through
-// simulated write onto the wire and read off of the wire.
-// The differences between requests are detailed in the net/http package.
-func newRequest(method, url string) *http.Request {
- req, err := http.NewRequest(method, url, nil)
- if err != nil {
- panic(err)
- }
- // extract the escaped original host+path from url
- // http://localhost/path/here?v=1#frag -> //localhost/path/here
- opaque := ""
- if i := len(req.URL.Scheme); i > 0 {
- opaque = url[i+1:]
- }
-
- if i := strings.LastIndex(opaque, "?"); i > -1 {
- opaque = opaque[:i]
- }
- if i := strings.LastIndex(opaque, "#"); i > -1 {
- opaque = opaque[:i]
- }
-
- // Escaped host+path workaround as detailed in https://golang.org/pkg/net/url/#URL
- // for < 1.5 client side workaround
- req.URL.Opaque = opaque
-
- // Simulate writing to wire
- var buff bytes.Buffer
- req.Write(&buff)
- ioreader := bufio.NewReader(&buff)
-
- // Parse request off of 'wire'
- req, err = http.ReadRequest(ioreader)
- if err != nil {
- panic(err)
- }
- return req
-}
diff --git a/vendor/github.com/gorilla/mux/old_test.go b/vendor/github.com/gorilla/mux/old_test.go
deleted file mode 100644
index b228983c4..000000000
--- a/vendor/github.com/gorilla/mux/old_test.go
+++ /dev/null
@@ -1,704 +0,0 @@
-// Old tests ported to Go1. This is a mess. Want to drop it one day.
-
-// Copyright 2011 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 mux
-
-import (
- "bytes"
- "net/http"
- "testing"
-)
-
-// ----------------------------------------------------------------------------
-// ResponseRecorder
-// ----------------------------------------------------------------------------
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// ResponseRecorder is an implementation of http.ResponseWriter that
-// records its mutations for later inspection in tests.
-type ResponseRecorder struct {
- Code int // the HTTP response code from WriteHeader
- HeaderMap http.Header // the HTTP response headers
- Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to
- Flushed bool
-}
-
-// NewRecorder returns an initialized ResponseRecorder.
-func NewRecorder() *ResponseRecorder {
- return &ResponseRecorder{
- HeaderMap: make(http.Header),
- Body: new(bytes.Buffer),
- }
-}
-
-// Header returns the response headers.
-func (rw *ResponseRecorder) Header() http.Header {
- return rw.HeaderMap
-}
-
-// Write always succeeds and writes to rw.Body, if not nil.
-func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
- if rw.Body != nil {
- rw.Body.Write(buf)
- }
- if rw.Code == 0 {
- rw.Code = http.StatusOK
- }
- return len(buf), nil
-}
-
-// WriteHeader sets rw.Code.
-func (rw *ResponseRecorder) WriteHeader(code int) {
- rw.Code = code
-}
-
-// Flush sets rw.Flushed to true.
-func (rw *ResponseRecorder) Flush() {
- rw.Flushed = true
-}
-
-// ----------------------------------------------------------------------------
-
-func TestRouteMatchers(t *testing.T) {
- var scheme, host, path, query, method string
- var headers map[string]string
- var resultVars map[bool]map[string]string
-
- router := NewRouter()
- router.NewRoute().Host("{var1}.google.com").
- Path("/{var2:[a-z]+}/{var3:[0-9]+}").
- Queries("foo", "bar").
- Methods("GET").
- Schemes("https").
- Headers("x-requested-with", "XMLHttpRequest")
- router.NewRoute().Host("www.{var4}.com").
- PathPrefix("/foo/{var5:[a-z]+}/{var6:[0-9]+}").
- Queries("baz", "ding").
- Methods("POST").
- Schemes("http").
- Headers("Content-Type", "application/json")
-
- reset := func() {
- // Everything match.
- scheme = "https"
- host = "www.google.com"
- path = "/product/42"
- query = "?foo=bar"
- method = "GET"
- headers = map[string]string{"X-Requested-With": "XMLHttpRequest"}
- resultVars = map[bool]map[string]string{
- true: {"var1": "www", "var2": "product", "var3": "42"},
- false: {},
- }
- }
-
- reset2 := func() {
- // Everything match.
- scheme = "http"
- host = "www.google.com"
- path = "/foo/product/42/path/that/is/ignored"
- query = "?baz=ding"
- method = "POST"
- headers = map[string]string{"Content-Type": "application/json"}
- resultVars = map[bool]map[string]string{
- true: {"var4": "google", "var5": "product", "var6": "42"},
- false: {},
- }
- }
-
- match := func(shouldMatch bool) {
- url := scheme + "://" + host + path + query
- request, _ := http.NewRequest(method, url, nil)
- for key, value := range headers {
- request.Header.Add(key, value)
- }
-
- var routeMatch RouteMatch
- matched := router.Match(request, &routeMatch)
- if matched != shouldMatch {
- t.Errorf("Expected: %v\nGot: %v\nRequest: %v %v", shouldMatch, matched, request.Method, url)
- }
-
- if matched {
- currentRoute := routeMatch.Route
- if currentRoute == nil {
- t.Errorf("Expected a current route.")
- }
- vars := routeMatch.Vars
- expectedVars := resultVars[shouldMatch]
- if len(vars) != len(expectedVars) {
- t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars)
- }
- for name, value := range vars {
- if expectedVars[name] != value {
- t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars)
- }
- }
- }
- }
-
- // 1st route --------------------------------------------------------------
-
- // Everything match.
- reset()
- match(true)
-
- // Scheme doesn't match.
- reset()
- scheme = "http"
- match(false)
-
- // Host doesn't match.
- reset()
- host = "www.mygoogle.com"
- match(false)
-
- // Path doesn't match.
- reset()
- path = "/product/notdigits"
- match(false)
-
- // Query doesn't match.
- reset()
- query = "?foo=baz"
- match(false)
-
- // Method doesn't match.
- reset()
- method = "POST"
- match(false)
-
- // Header doesn't match.
- reset()
- headers = map[string]string{}
- match(false)
-
- // Everything match, again.
- reset()
- match(true)
-
- // 2nd route --------------------------------------------------------------
- // Everything match.
- reset2()
- match(true)
-
- // Scheme doesn't match.
- reset2()
- scheme = "https"
- match(false)
-
- // Host doesn't match.
- reset2()
- host = "sub.google.com"
- match(false)
-
- // Path doesn't match.
- reset2()
- path = "/bar/product/42"
- match(false)
-
- // Query doesn't match.
- reset2()
- query = "?foo=baz"
- match(false)
-
- // Method doesn't match.
- reset2()
- method = "GET"
- match(false)
-
- // Header doesn't match.
- reset2()
- headers = map[string]string{}
- match(false)
-
- // Everything match, again.
- reset2()
- match(true)
-}
-
-type headerMatcherTest struct {
- matcher headerMatcher
- headers map[string]string
- result bool
-}
-
-var headerMatcherTests = []headerMatcherTest{
- {
- matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}),
- headers: map[string]string{"X-Requested-With": "XMLHttpRequest"},
- result: true,
- },
- {
- matcher: headerMatcher(map[string]string{"x-requested-with": ""}),
- headers: map[string]string{"X-Requested-With": "anything"},
- result: true,
- },
- {
- matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}),
- headers: map[string]string{},
- result: false,
- },
-}
-
-type hostMatcherTest struct {
- matcher *Route
- url string
- vars map[string]string
- result bool
-}
-
-var hostMatcherTests = []hostMatcherTest{
- {
- matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"),
- url: "http://abc.def.ghi/",
- vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"},
- result: true,
- },
- {
- matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"),
- url: "http://a.b.c/",
- vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"},
- result: false,
- },
-}
-
-type methodMatcherTest struct {
- matcher methodMatcher
- method string
- result bool
-}
-
-var methodMatcherTests = []methodMatcherTest{
- {
- matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
- method: "GET",
- result: true,
- },
- {
- matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
- method: "POST",
- result: true,
- },
- {
- matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
- method: "PUT",
- result: true,
- },
- {
- matcher: methodMatcher([]string{"GET", "POST", "PUT"}),
- method: "DELETE",
- result: false,
- },
-}
-
-type pathMatcherTest struct {
- matcher *Route
- url string
- vars map[string]string
- result bool
-}
-
-var pathMatcherTests = []pathMatcherTest{
- {
- matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"),
- url: "http://localhost:8080/123/456/789",
- vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"},
- result: true,
- },
- {
- matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"),
- url: "http://localhost:8080/1/2/3",
- vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"},
- result: false,
- },
-}
-
-type schemeMatcherTest struct {
- matcher schemeMatcher
- url string
- result bool
-}
-
-var schemeMatcherTests = []schemeMatcherTest{
- {
- matcher: schemeMatcher([]string{"http", "https"}),
- url: "http://localhost:8080/",
- result: true,
- },
- {
- matcher: schemeMatcher([]string{"http", "https"}),
- url: "https://localhost:8080/",
- result: true,
- },
- {
- matcher: schemeMatcher([]string{"https"}),
- url: "http://localhost:8080/",
- result: false,
- },
- {
- matcher: schemeMatcher([]string{"http"}),
- url: "https://localhost:8080/",
- result: false,
- },
-}
-
-type urlBuildingTest struct {
- route *Route
- vars []string
- url string
-}
-
-var urlBuildingTests = []urlBuildingTest{
- {
- route: new(Route).Host("foo.domain.com"),
- vars: []string{},
- url: "http://foo.domain.com",
- },
- {
- route: new(Route).Host("{subdomain}.domain.com"),
- vars: []string{"subdomain", "bar"},
- url: "http://bar.domain.com",
- },
- {
- route: new(Route).Host("foo.domain.com").Path("/articles"),
- vars: []string{},
- url: "http://foo.domain.com/articles",
- },
- {
- route: new(Route).Path("/articles"),
- vars: []string{},
- url: "/articles",
- },
- {
- route: new(Route).Path("/articles/{category}/{id:[0-9]+}"),
- vars: []string{"category", "technology", "id", "42"},
- url: "/articles/technology/42",
- },
- {
- route: new(Route).Host("{subdomain}.domain.com").Path("/articles/{category}/{id:[0-9]+}"),
- vars: []string{"subdomain", "foo", "category", "technology", "id", "42"},
- url: "http://foo.domain.com/articles/technology/42",
- },
-}
-
-func TestHeaderMatcher(t *testing.T) {
- for _, v := range headerMatcherTests {
- request, _ := http.NewRequest("GET", "http://localhost:8080/", nil)
- for key, value := range v.headers {
- request.Header.Add(key, value)
- }
- var routeMatch RouteMatch
- result := v.matcher.Match(request, &routeMatch)
- if result != v.result {
- if v.result {
- t.Errorf("%#v: should match %v.", v.matcher, request.Header)
- } else {
- t.Errorf("%#v: should not match %v.", v.matcher, request.Header)
- }
- }
- }
-}
-
-func TestHostMatcher(t *testing.T) {
- for _, v := range hostMatcherTests {
- request, _ := http.NewRequest("GET", v.url, nil)
- var routeMatch RouteMatch
- result := v.matcher.Match(request, &routeMatch)
- vars := routeMatch.Vars
- if result != v.result {
- if v.result {
- t.Errorf("%#v: should match %v.", v.matcher, v.url)
- } else {
- t.Errorf("%#v: should not match %v.", v.matcher, v.url)
- }
- }
- if result {
- if len(vars) != len(v.vars) {
- t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars))
- }
- for name, value := range vars {
- if v.vars[name] != value {
- t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value)
- }
- }
- } else {
- if len(vars) != 0 {
- t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars))
- }
- }
- }
-}
-
-func TestMethodMatcher(t *testing.T) {
- for _, v := range methodMatcherTests {
- request, _ := http.NewRequest(v.method, "http://localhost:8080/", nil)
- var routeMatch RouteMatch
- result := v.matcher.Match(request, &routeMatch)
- if result != v.result {
- if v.result {
- t.Errorf("%#v: should match %v.", v.matcher, v.method)
- } else {
- t.Errorf("%#v: should not match %v.", v.matcher, v.method)
- }
- }
- }
-}
-
-func TestPathMatcher(t *testing.T) {
- for _, v := range pathMatcherTests {
- request, _ := http.NewRequest("GET", v.url, nil)
- var routeMatch RouteMatch
- result := v.matcher.Match(request, &routeMatch)
- vars := routeMatch.Vars
- if result != v.result {
- if v.result {
- t.Errorf("%#v: should match %v.", v.matcher, v.url)
- } else {
- t.Errorf("%#v: should not match %v.", v.matcher, v.url)
- }
- }
- if result {
- if len(vars) != len(v.vars) {
- t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars))
- }
- for name, value := range vars {
- if v.vars[name] != value {
- t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value)
- }
- }
- } else {
- if len(vars) != 0 {
- t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars))
- }
- }
- }
-}
-
-func TestSchemeMatcher(t *testing.T) {
- for _, v := range schemeMatcherTests {
- request, _ := http.NewRequest("GET", v.url, nil)
- var routeMatch RouteMatch
- result := v.matcher.Match(request, &routeMatch)
- if result != v.result {
- if v.result {
- t.Errorf("%#v: should match %v.", v.matcher, v.url)
- } else {
- t.Errorf("%#v: should not match %v.", v.matcher, v.url)
- }
- }
- }
-}
-
-func TestUrlBuilding(t *testing.T) {
-
- for _, v := range urlBuildingTests {
- u, _ := v.route.URL(v.vars...)
- url := u.String()
- if url != v.url {
- t.Errorf("expected %v, got %v", v.url, url)
- /*
- reversePath := ""
- reverseHost := ""
- if v.route.pathTemplate != nil {
- reversePath = v.route.pathTemplate.Reverse
- }
- if v.route.hostTemplate != nil {
- reverseHost = v.route.hostTemplate.Reverse
- }
-
- t.Errorf("%#v:\nexpected: %q\ngot: %q\nreverse path: %q\nreverse host: %q", v.route, v.url, url, reversePath, reverseHost)
- */
- }
- }
-
- ArticleHandler := func(w http.ResponseWriter, r *http.Request) {
- }
-
- router := NewRouter()
- router.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article")
-
- url, _ := router.Get("article").URL("category", "technology", "id", "42")
- expected := "/articles/technology/42"
- if url.String() != expected {
- t.Errorf("Expected %v, got %v", expected, url.String())
- }
-}
-
-func TestMatchedRouteName(t *testing.T) {
- routeName := "stock"
- router := NewRouter()
- route := router.NewRoute().Path("/products/").Name(routeName)
-
- url := "http://www.example.com/products/"
- request, _ := http.NewRequest("GET", url, nil)
- var rv RouteMatch
- ok := router.Match(request, &rv)
-
- if !ok || rv.Route != route {
- t.Errorf("Expected same route, got %+v.", rv.Route)
- }
-
- retName := rv.Route.GetName()
- if retName != routeName {
- t.Errorf("Expected %q, got %q.", routeName, retName)
- }
-}
-
-func TestSubRouting(t *testing.T) {
- // Example from docs.
- router := NewRouter()
- subrouter := router.NewRoute().Host("www.example.com").Subrouter()
- route := subrouter.NewRoute().Path("/products/").Name("products")
-
- url := "http://www.example.com/products/"
- request, _ := http.NewRequest("GET", url, nil)
- var rv RouteMatch
- ok := router.Match(request, &rv)
-
- if !ok || rv.Route != route {
- t.Errorf("Expected same route, got %+v.", rv.Route)
- }
-
- u, _ := router.Get("products").URL()
- builtURL := u.String()
- // Yay, subroute aware of the domain when building!
- if builtURL != url {
- t.Errorf("Expected %q, got %q.", url, builtURL)
- }
-}
-
-func TestVariableNames(t *testing.T) {
- route := new(Route).Host("{arg1}.domain.com").Path("/{arg1}/{arg2:[0-9]+}")
- if route.err == nil {
- t.Errorf("Expected error for duplicated variable names")
- }
-}
-
-func TestRedirectSlash(t *testing.T) {
- var route *Route
- var routeMatch RouteMatch
- r := NewRouter()
-
- r.StrictSlash(false)
- route = r.NewRoute()
- if route.strictSlash != false {
- t.Errorf("Expected false redirectSlash.")
- }
-
- r.StrictSlash(true)
- route = r.NewRoute()
- if route.strictSlash != true {
- t.Errorf("Expected true redirectSlash.")
- }
-
- route = new(Route)
- route.strictSlash = true
- route.Path("/{arg1}/{arg2:[0-9]+}/")
- request, _ := http.NewRequest("GET", "http://localhost/foo/123", nil)
- routeMatch = RouteMatch{}
- _ = route.Match(request, &routeMatch)
- vars := routeMatch.Vars
- if vars["arg1"] != "foo" {
- t.Errorf("Expected foo.")
- }
- if vars["arg2"] != "123" {
- t.Errorf("Expected 123.")
- }
- rsp := NewRecorder()
- routeMatch.Handler.ServeHTTP(rsp, request)
- if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123/" {
- t.Errorf("Expected redirect header.")
- }
-
- route = new(Route)
- route.strictSlash = true
- route.Path("/{arg1}/{arg2:[0-9]+}")
- request, _ = http.NewRequest("GET", "http://localhost/foo/123/", nil)
- routeMatch = RouteMatch{}
- _ = route.Match(request, &routeMatch)
- vars = routeMatch.Vars
- if vars["arg1"] != "foo" {
- t.Errorf("Expected foo.")
- }
- if vars["arg2"] != "123" {
- t.Errorf("Expected 123.")
- }
- rsp = NewRecorder()
- routeMatch.Handler.ServeHTTP(rsp, request)
- if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123" {
- t.Errorf("Expected redirect header.")
- }
-}
-
-// Test for the new regexp library, still not available in stable Go.
-func TestNewRegexp(t *testing.T) {
- var p *routeRegexp
- var matches []string
-
- tests := map[string]map[string][]string{
- "/{foo:a{2}}": {
- "/a": nil,
- "/aa": {"aa"},
- "/aaa": nil,
- "/aaaa": nil,
- },
- "/{foo:a{2,}}": {
- "/a": nil,
- "/aa": {"aa"},
- "/aaa": {"aaa"},
- "/aaaa": {"aaaa"},
- },
- "/{foo:a{2,3}}": {
- "/a": nil,
- "/aa": {"aa"},
- "/aaa": {"aaa"},
- "/aaaa": nil,
- },
- "/{foo:[a-z]{3}}/{bar:[a-z]{2}}": {
- "/a": nil,
- "/ab": nil,
- "/abc": nil,
- "/abcd": nil,
- "/abc/ab": {"abc", "ab"},
- "/abc/abc": nil,
- "/abcd/ab": nil,
- },
- `/{foo:\w{3,}}/{bar:\d{2,}}`: {
- "/a": nil,
- "/ab": nil,
- "/abc": nil,
- "/abc/1": nil,
- "/abc/12": {"abc", "12"},
- "/abcd/12": {"abcd", "12"},
- "/abcd/123": {"abcd", "123"},
- },
- }
-
- for pattern, paths := range tests {
- p, _ = newRouteRegexp(pattern, regexpTypePath, routeRegexpOptions{})
- for path, result := range paths {
- matches = p.regexp.FindStringSubmatch(path)
- if result == nil {
- if matches != nil {
- t.Errorf("%v should not match %v.", pattern, path)
- }
- } else {
- if len(matches) != len(result)+1 {
- t.Errorf("Expected %v matches, got %v.", len(result)+1, len(matches))
- } else {
- for k, v := range result {
- if matches[k+1] != v {
- t.Errorf("Expected %v, got %v.", v, matches[k+1])
- }
- }
- }
- }
- }
- }
-}
diff --git a/vendor/github.com/gorilla/schema/cache.go b/vendor/github.com/gorilla/schema/cache.go
index afa20a3a3..73b75f48d 100644
--- a/vendor/github.com/gorilla/schema/cache.go
+++ b/vendor/github.com/gorilla/schema/cache.go
@@ -63,7 +63,7 @@ func (c *cache) parsePath(p string, t reflect.Type) ([]pathPart, error) {
}
// Valid field. Append index.
path = append(path, field.name)
- if field.ss {
+ if field.isSliceOfStructs && (!field.unmarshalerInfo.IsValid || (field.unmarshalerInfo.IsValid && field.unmarshalerInfo.IsSliceElement)) {
// Parse a special case: slices of structs.
// i+1 must be the slice index.
//
@@ -142,7 +142,7 @@ func (c *cache) create(t reflect.Type, info *structInfo) *structInfo {
c.create(ft, info)
for _, fi := range info.fields[bef:len(info.fields)] {
// exclude required check because duplicated to embedded field
- fi.required = false
+ fi.isRequired = false
}
}
}
@@ -162,6 +162,7 @@ func (c *cache) createField(field reflect.StructField, info *structInfo) {
// First let's get the basic type.
isSlice, isStruct := false, false
ft := field.Type
+ m := isTextUnmarshaler(reflect.Zero(ft))
if ft.Kind() == reflect.Ptr {
ft = ft.Elem()
}
@@ -185,12 +186,13 @@ func (c *cache) createField(field reflect.StructField, info *structInfo) {
}
info.fields = append(info.fields, &fieldInfo{
- typ: field.Type,
- name: field.Name,
- ss: isSlice && isStruct,
- alias: alias,
- anon: field.Anonymous,
- required: options.Contains("required"),
+ typ: field.Type,
+ name: field.Name,
+ alias: alias,
+ unmarshalerInfo: m,
+ isSliceOfStructs: isSlice && isStruct,
+ isAnonymous: field.Anonymous,
+ isRequired: options.Contains("required"),
})
}
@@ -215,12 +217,18 @@ func (i *structInfo) get(alias string) *fieldInfo {
}
type fieldInfo struct {
- typ reflect.Type
- name string // field name in the struct.
- ss bool // true if this is a slice of structs.
- alias string
- anon bool // is an embedded field
- required bool // tag option
+ typ reflect.Type
+ // name is the field name in the struct.
+ name string
+ alias string
+ // unmarshalerInfo contains information regarding the
+ // encoding.TextUnmarshaler implementation of the field type.
+ unmarshalerInfo unmarshaler
+ // isSliceOfStructs indicates if the field type is a slice of structs.
+ isSliceOfStructs bool
+ // isAnonymous indicates whether the field is embedded in the struct.
+ isAnonymous bool
+ isRequired bool
}
type pathPart struct {
diff --git a/vendor/github.com/gorilla/schema/decoder.go b/vendor/github.com/gorilla/schema/decoder.go
index e49b53c87..5352a908b 100644
--- a/vendor/github.com/gorilla/schema/decoder.go
+++ b/vendor/github.com/gorilla/schema/decoder.go
@@ -106,7 +106,7 @@ func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string, prefix
if f.typ.Kind() == reflect.Struct {
err := d.checkRequired(f.typ, src, prefix+f.alias+".")
if err != nil {
- if !f.anon {
+ if !f.isAnonymous {
return err
}
// check embedded parent field.
@@ -116,7 +116,7 @@ func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string, prefix
}
}
}
- if f.required {
+ if f.isRequired {
key := f.alias
if prefix != "" {
key = prefix + key
@@ -185,7 +185,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
// Get the converter early in case there is one for a slice type.
conv := d.cache.converter(t)
m := isTextUnmarshaler(v)
- if conv == nil && t.Kind() == reflect.Slice && m.IsSlice {
+ if conv == nil && t.Kind() == reflect.Slice && m.IsSliceElement {
var items []reflect.Value
elemT := t.Elem()
isPtrElem := elemT.Kind() == reflect.Ptr
@@ -211,7 +211,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
}
} else if m.IsValid {
u := reflect.New(elemT)
- if m.IsPtr {
+ if m.IsSliceElementPtr {
u = reflect.New(reflect.PtrTo(elemT).Elem())
}
if err := u.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(value)); err != nil {
@@ -222,7 +222,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
Err: err,
}
}
- if m.IsPtr {
+ if m.IsSliceElementPtr {
items = append(items, u.Elem().Addr())
} else if u.Kind() == reflect.Ptr {
items = append(items, u.Elem())
@@ -283,11 +283,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
val = values[len(values)-1]
}
- if val == "" {
- if d.zeroEmpty {
- v.Set(reflect.Zero(t))
- }
- } else if conv != nil {
+ if conv != nil {
if value := conv(val); value.IsValid() {
v.Set(value.Convert(t))
} else {
@@ -298,15 +294,32 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
}
}
} else if m.IsValid {
- // If the value implements the encoding.TextUnmarshaler interface
- // apply UnmarshalText as the converter
- if err := m.Unmarshaler.UnmarshalText([]byte(val)); err != nil {
- return ConversionError{
- Key: path,
- Type: t,
- Index: -1,
- Err: err,
+ if m.IsPtr {
+ u := reflect.New(v.Type())
+ if err := u.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(val)); err != nil {
+ return ConversionError{
+ Key: path,
+ Type: t,
+ Index: -1,
+ Err: err,
+ }
}
+ v.Set(reflect.Indirect(u))
+ } else {
+ // If the value implements the encoding.TextUnmarshaler interface
+ // apply UnmarshalText as the converter
+ if err := m.Unmarshaler.UnmarshalText([]byte(val)); err != nil {
+ return ConversionError{
+ Key: path,
+ Type: t,
+ Index: -1,
+ Err: err,
+ }
+ }
+ }
+ } else if val == "" {
+ if d.zeroEmpty {
+ v.Set(reflect.Zero(t))
}
} else if conv := builtinConverters[t.Kind()]; conv != nil {
if value := conv(val); value.IsValid() {
@@ -326,18 +339,18 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
}
func isTextUnmarshaler(v reflect.Value) unmarshaler {
-
// Create a new unmarshaller instance
m := unmarshaler{}
-
- // As the UnmarshalText function should be applied
- // to the pointer of the type, we convert the value to pointer.
- if v.CanAddr() {
- v = v.Addr()
- }
if m.Unmarshaler, m.IsValid = v.Interface().(encoding.TextUnmarshaler); m.IsValid {
return m
}
+ // As the UnmarshalText function should be applied to the pointer of the
+ // type, we check that type to see if it implements the necessary
+ // method.
+ if m.Unmarshaler, m.IsValid = reflect.New(v.Type()).Interface().(encoding.TextUnmarshaler); m.IsValid {
+ m.IsPtr = true
+ return m
+ }
// if v is []T or *[]T create new T
t := v.Type()
@@ -345,12 +358,17 @@ func isTextUnmarshaler(v reflect.Value) unmarshaler {
t = t.Elem()
}
if t.Kind() == reflect.Slice {
- // if t is a pointer slice, check if it implements encoding.TextUnmarshaler
- m.IsSlice = true
+ // Check if the slice implements encoding.TextUnmarshaller
+ if m.Unmarshaler, m.IsValid = v.Interface().(encoding.TextUnmarshaler); m.IsValid {
+ return m
+ }
+ // If t is a pointer slice, check if its elements implement
+ // encoding.TextUnmarshaler
+ m.IsSliceElement = true
if t = t.Elem(); t.Kind() == reflect.Ptr {
t = reflect.PtrTo(t.Elem())
v = reflect.Zero(t)
- m.IsPtr = true
+ m.IsSliceElementPtr = true
m.Unmarshaler, m.IsValid = v.Interface().(encoding.TextUnmarshaler)
return m
}
@@ -365,9 +383,18 @@ func isTextUnmarshaler(v reflect.Value) unmarshaler {
// unmarshaller contains information about a TextUnmarshaler type
type unmarshaler struct {
Unmarshaler encoding.TextUnmarshaler
- IsSlice bool
- IsPtr bool
- IsValid bool
+ // IsValid indicates whether the resolved type indicated by the other
+ // flags implements the encoding.TextUnmarshaler interface.
+ IsValid bool
+ // IsPtr indicates that the resolved type is the pointer of the original
+ // type.
+ IsPtr bool
+ // IsSliceElement indicates that the resolved type is a slice element of
+ // the original type.
+ IsSliceElement bool
+ // IsSliceElementPtr indicates that the resolved type is a pointer to a
+ // slice element of the original type.
+ IsSliceElementPtr bool
}
// Errors ---------------------------------------------------------------------
diff --git a/vendor/github.com/gorilla/schema/decoder_test.go b/vendor/github.com/gorilla/schema/decoder_test.go
deleted file mode 100644
index 18b3b3270..000000000
--- a/vendor/github.com/gorilla/schema/decoder_test.go
+++ /dev/null
@@ -1,1693 +0,0 @@
-// Copyright 2012 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 schema
-
-import (
- "encoding/hex"
- "errors"
- "reflect"
- "strings"
- "testing"
- "time"
-)
-
-type IntAlias int
-
-type rudeBool bool
-
-func (id *rudeBool) UnmarshalText(text []byte) error {
- value := string(text)
- switch {
- case strings.EqualFold("Yup", value):
- *id = true
- case strings.EqualFold("Nope", value):
- *id = false
- default:
- return errors.New("value must be yup or nope")
- }
- return nil
-}
-
-// All cases we want to cover, in a nutshell.
-type S1 struct {
- F01 int `schema:"f1"`
- F02 *int `schema:"f2"`
- F03 []int `schema:"f3"`
- F04 []*int `schema:"f4"`
- F05 *[]int `schema:"f5"`
- F06 *[]*int `schema:"f6"`
- F07 S2 `schema:"f7"`
- F08 *S1 `schema:"f8"`
- F09 int `schema:"-"`
- F10 []S1 `schema:"f10"`
- F11 []*S1 `schema:"f11"`
- F12 *[]S1 `schema:"f12"`
- F13 *[]*S1 `schema:"f13"`
- F14 int `schema:"f14"`
- F15 IntAlias `schema:"f15"`
- F16 []IntAlias `schema:"f16"`
- F17 S19 `schema:"f17"`
- F18 rudeBool `schema:"f18"`
- F19 *rudeBool `schema:"f19"`
- F20 []rudeBool `schema:"f20"`
- F21 []*rudeBool `schema:"f21"`
-}
-
-type S2 struct {
- F01 *[]*int `schema:"f1"`
-}
-
-type S19 [2]byte
-
-func (id *S19) UnmarshalText(text []byte) error {
- buf, err := hex.DecodeString(string(text))
- if err != nil {
- return err
- }
- if len(buf) > len(*id) {
- return errors.New("out of range")
- }
- for i := range buf {
- (*id)[i] = buf[i]
- }
- return nil
-}
-
-func TestAll(t *testing.T) {
- v := map[string][]string{
- "f1": {"1"},
- "f2": {"2"},
- "f3": {"31", "32"},
- "f4": {"41", "42"},
- "f5": {"51", "52"},
- "f6": {"61", "62"},
- "f7.f1": {"71", "72"},
- "f8.f8.f7.f1": {"81", "82"},
- "f9": {"9"},
- "f10.0.f10.0.f6": {"101", "102"},
- "f10.0.f10.1.f6": {"103", "104"},
- "f11.0.f11.0.f6": {"111", "112"},
- "f11.0.f11.1.f6": {"113", "114"},
- "f12.0.f12.0.f6": {"121", "122"},
- "f12.0.f12.1.f6": {"123", "124"},
- "f13.0.f13.0.f6": {"131", "132"},
- "f13.0.f13.1.f6": {"133", "134"},
- "f14": {},
- "f15": {"151"},
- "f16": {"161", "162"},
- "f17": {"1a2b"},
- "f18": {"yup"},
- "f19": {"nope"},
- "f20": {"nope", "yup"},
- "f21": {"yup", "nope"},
- }
- f2 := 2
- f41, f42 := 41, 42
- f61, f62 := 61, 62
- f71, f72 := 71, 72
- f81, f82 := 81, 82
- f101, f102, f103, f104 := 101, 102, 103, 104
- f111, f112, f113, f114 := 111, 112, 113, 114
- f121, f122, f123, f124 := 121, 122, 123, 124
- f131, f132, f133, f134 := 131, 132, 133, 134
- var f151 IntAlias = 151
- var f161, f162 IntAlias = 161, 162
- var f152, f153 rudeBool = true, false
- e := S1{
- F01: 1,
- F02: &f2,
- F03: []int{31, 32},
- F04: []*int{&f41, &f42},
- F05: &[]int{51, 52},
- F06: &[]*int{&f61, &f62},
- F07: S2{
- F01: &[]*int{&f71, &f72},
- },
- F08: &S1{
- F08: &S1{
- F07: S2{
- F01: &[]*int{&f81, &f82},
- },
- },
- },
- F09: 0,
- F10: []S1{
- S1{
- F10: []S1{
- S1{F06: &[]*int{&f101, &f102}},
- S1{F06: &[]*int{&f103, &f104}},
- },
- },
- },
- F11: []*S1{
- &S1{
- F11: []*S1{
- &S1{F06: &[]*int{&f111, &f112}},
- &S1{F06: &[]*int{&f113, &f114}},
- },
- },
- },
- F12: &[]S1{
- S1{
- F12: &[]S1{
- S1{F06: &[]*int{&f121, &f122}},
- S1{F06: &[]*int{&f123, &f124}},
- },
- },
- },
- F13: &[]*S1{
- &S1{
- F13: &[]*S1{
- &S1{F06: &[]*int{&f131, &f132}},
- &S1{F06: &[]*int{&f133, &f134}},
- },
- },
- },
- F14: 0,
- F15: f151,
- F16: []IntAlias{f161, f162},
- F17: S19{0x1a, 0x2b},
- F18: f152,
- F19: &f153,
- F20: []rudeBool{f153, f152},
- F21: []*rudeBool{&f152, &f153},
- }
-
- s := &S1{}
- _ = NewDecoder().Decode(s, v)
-
- vals := func(values []*int) []int {
- r := make([]int, len(values))
- for k, v := range values {
- r[k] = *v
- }
- return r
- }
-
- if s.F01 != e.F01 {
- t.Errorf("f1: expected %v, got %v", e.F01, s.F01)
- }
- if s.F02 == nil {
- t.Errorf("f2: expected %v, got nil", *e.F02)
- } else if *s.F02 != *e.F02 {
- t.Errorf("f2: expected %v, got %v", *e.F02, *s.F02)
- }
- if s.F03 == nil {
- t.Errorf("f3: expected %v, got nil", e.F03)
- } else if len(s.F03) != 2 || s.F03[0] != e.F03[0] || s.F03[1] != e.F03[1] {
- t.Errorf("f3: expected %v, got %v", e.F03, s.F03)
- }
- if s.F04 == nil {
- t.Errorf("f4: expected %v, got nil", e.F04)
- } else {
- if len(s.F04) != 2 || *(s.F04)[0] != *(e.F04)[0] || *(s.F04)[1] != *(e.F04)[1] {
- t.Errorf("f4: expected %v, got %v", vals(e.F04), vals(s.F04))
- }
- }
- if s.F05 == nil {
- t.Errorf("f5: expected %v, got nil", e.F05)
- } else {
- sF05, eF05 := *s.F05, *e.F05
- if len(sF05) != 2 || sF05[0] != eF05[0] || sF05[1] != eF05[1] {
- t.Errorf("f5: expected %v, got %v", eF05, sF05)
- }
- }
- if s.F06 == nil {
- t.Errorf("f6: expected %v, got nil", vals(*e.F06))
- } else {
- sF06, eF06 := *s.F06, *e.F06
- if len(sF06) != 2 || *(sF06)[0] != *(eF06)[0] || *(sF06)[1] != *(eF06)[1] {
- t.Errorf("f6: expected %v, got %v", vals(eF06), vals(sF06))
- }
- }
- if s.F07.F01 == nil {
- t.Errorf("f7.f1: expected %v, got nil", vals(*e.F07.F01))
- } else {
- sF07, eF07 := *s.F07.F01, *e.F07.F01
- if len(sF07) != 2 || *(sF07)[0] != *(eF07)[0] || *(sF07)[1] != *(eF07)[1] {
- t.Errorf("f7.f1: expected %v, got %v", vals(eF07), vals(sF07))
- }
- }
- if s.F08 == nil {
- t.Errorf("f8: got nil")
- } else if s.F08.F08 == nil {
- t.Errorf("f8.f8: got nil")
- } else if s.F08.F08.F07.F01 == nil {
- t.Errorf("f8.f8.f7.f1: expected %v, got nil", vals(*e.F08.F08.F07.F01))
- } else {
- sF08, eF08 := *s.F08.F08.F07.F01, *e.F08.F08.F07.F01
- if len(sF08) != 2 || *(sF08)[0] != *(eF08)[0] || *(sF08)[1] != *(eF08)[1] {
- t.Errorf("f8.f8.f7.f1: expected %v, got %v", vals(eF08), vals(sF08))
- }
- }
- if s.F09 != e.F09 {
- t.Errorf("f9: expected %v, got %v", e.F09, s.F09)
- }
- if s.F10 == nil {
- t.Errorf("f10: got nil")
- } else if len(s.F10) != 1 {
- t.Errorf("f10: expected 1 element, got %v", s.F10)
- } else {
- if len(s.F10[0].F10) != 2 {
- t.Errorf("f10.0.f10: expected 1 element, got %v", s.F10[0].F10)
- } else {
- sF10, eF10 := *s.F10[0].F10[0].F06, *e.F10[0].F10[0].F06
- if sF10 == nil {
- t.Errorf("f10.0.f10.0.f6: expected %v, got nil", vals(eF10))
- } else {
- if len(sF10) != 2 || *(sF10)[0] != *(eF10)[0] || *(sF10)[1] != *(eF10)[1] {
- t.Errorf("f10.0.f10.0.f6: expected %v, got %v", vals(eF10), vals(sF10))
- }
- }
- sF10, eF10 = *s.F10[0].F10[1].F06, *e.F10[0].F10[1].F06
- if sF10 == nil {
- t.Errorf("f10.0.f10.0.f6: expected %v, got nil", vals(eF10))
- } else {
- if len(sF10) != 2 || *(sF10)[0] != *(eF10)[0] || *(sF10)[1] != *(eF10)[1] {
- t.Errorf("f10.0.f10.0.f6: expected %v, got %v", vals(eF10), vals(sF10))
- }
- }
- }
- }
- if s.F11 == nil {
- t.Errorf("f11: got nil")
- } else if len(s.F11) != 1 {
- t.Errorf("f11: expected 1 element, got %v", s.F11)
- } else {
- if len(s.F11[0].F11) != 2 {
- t.Errorf("f11.0.f11: expected 1 element, got %v", s.F11[0].F11)
- } else {
- sF11, eF11 := *s.F11[0].F11[0].F06, *e.F11[0].F11[0].F06
- if sF11 == nil {
- t.Errorf("f11.0.f11.0.f6: expected %v, got nil", vals(eF11))
- } else {
- if len(sF11) != 2 || *(sF11)[0] != *(eF11)[0] || *(sF11)[1] != *(eF11)[1] {
- t.Errorf("f11.0.f11.0.f6: expected %v, got %v", vals(eF11), vals(sF11))
- }
- }
- sF11, eF11 = *s.F11[0].F11[1].F06, *e.F11[0].F11[1].F06
- if sF11 == nil {
- t.Errorf("f11.0.f11.0.f6: expected %v, got nil", vals(eF11))
- } else {
- if len(sF11) != 2 || *(sF11)[0] != *(eF11)[0] || *(sF11)[1] != *(eF11)[1] {
- t.Errorf("f11.0.f11.0.f6: expected %v, got %v", vals(eF11), vals(sF11))
- }
- }
- }
- }
- if s.F12 == nil {
- t.Errorf("f12: got nil")
- } else if len(*s.F12) != 1 {
- t.Errorf("f12: expected 1 element, got %v", *s.F12)
- } else {
- sF12, eF12 := *(s.F12), *(e.F12)
- if len(*sF12[0].F12) != 2 {
- t.Errorf("f12.0.f12: expected 1 element, got %v", *sF12[0].F12)
- } else {
- sF122, eF122 := *(*sF12[0].F12)[0].F06, *(*eF12[0].F12)[0].F06
- if sF122 == nil {
- t.Errorf("f12.0.f12.0.f6: expected %v, got nil", vals(eF122))
- } else {
- if len(sF122) != 2 || *(sF122)[0] != *(eF122)[0] || *(sF122)[1] != *(eF122)[1] {
- t.Errorf("f12.0.f12.0.f6: expected %v, got %v", vals(eF122), vals(sF122))
- }
- }
- sF122, eF122 = *(*sF12[0].F12)[1].F06, *(*eF12[0].F12)[1].F06
- if sF122 == nil {
- t.Errorf("f12.0.f12.0.f6: expected %v, got nil", vals(eF122))
- } else {
- if len(sF122) != 2 || *(sF122)[0] != *(eF122)[0] || *(sF122)[1] != *(eF122)[1] {
- t.Errorf("f12.0.f12.0.f6: expected %v, got %v", vals(eF122), vals(sF122))
- }
- }
- }
- }
- if s.F13 == nil {
- t.Errorf("f13: got nil")
- } else if len(*s.F13) != 1 {
- t.Errorf("f13: expected 1 element, got %v", *s.F13)
- } else {
- sF13, eF13 := *(s.F13), *(e.F13)
- if len(*sF13[0].F13) != 2 {
- t.Errorf("f13.0.f13: expected 1 element, got %v", *sF13[0].F13)
- } else {
- sF132, eF132 := *(*sF13[0].F13)[0].F06, *(*eF13[0].F13)[0].F06
- if sF132 == nil {
- t.Errorf("f13.0.f13.0.f6: expected %v, got nil", vals(eF132))
- } else {
- if len(sF132) != 2 || *(sF132)[0] != *(eF132)[0] || *(sF132)[1] != *(eF132)[1] {
- t.Errorf("f13.0.f13.0.f6: expected %v, got %v", vals(eF132), vals(sF132))
- }
- }
- sF132, eF132 = *(*sF13[0].F13)[1].F06, *(*eF13[0].F13)[1].F06
- if sF132 == nil {
- t.Errorf("f13.0.f13.0.f6: expected %v, got nil", vals(eF132))
- } else {
- if len(sF132) != 2 || *(sF132)[0] != *(eF132)[0] || *(sF132)[1] != *(eF132)[1] {
- t.Errorf("f13.0.f13.0.f6: expected %v, got %v", vals(eF132), vals(sF132))
- }
- }
- }
- }
- if s.F14 != e.F14 {
- t.Errorf("f14: expected %v, got %v", e.F14, s.F14)
- }
- if s.F15 != e.F15 {
- t.Errorf("f15: expected %v, got %v", e.F15, s.F15)
- }
- if s.F16 == nil {
- t.Errorf("f16: nil")
- } else if len(s.F16) != len(e.F16) {
- t.Errorf("f16: expected len %d, got %d", len(e.F16), len(s.F16))
- } else if !reflect.DeepEqual(s.F16, e.F16) {
- t.Errorf("f16: expected %v, got %v", e.F16, s.F16)
- }
- if s.F17 != e.F17 {
- t.Errorf("f17: expected %v, got %v", e.F17, s.F17)
- }
- if s.F18 != e.F18 {
- t.Errorf("f18: expected %v, got %v", e.F18, s.F18)
- }
- if *s.F19 != *e.F19 {
- t.Errorf("f19: expected %v, got %v", *e.F19, *s.F19)
- }
- if s.F20 == nil {
- t.Errorf("f20: nil")
- } else if len(s.F20) != len(e.F20) {
- t.Errorf("f20: expected %v, got %v", e.F20, s.F20)
- } else if !reflect.DeepEqual(s.F20, e.F20) {
- t.Errorf("f20: expected %v, got %v", e.F20, s.F20)
- }
- if s.F21 == nil {
- t.Errorf("f21: nil")
- } else if len(s.F21) != len(e.F21) {
- t.Errorf("f21: expected length %d, got %d", len(e.F21), len(s.F21))
- } else if !reflect.DeepEqual(s.F21, e.F21) {
- t.Errorf("f21: expected %v, got %v", e.F21, s.F21)
- }
-}
-
-func BenchmarkAll(b *testing.B) {
- v := map[string][]string{
- "f1": {"1"},
- "f2": {"2"},
- "f3": {"31", "32"},
- "f4": {"41", "42"},
- "f5": {"51", "52"},
- "f6": {"61", "62"},
- "f7.f1": {"71", "72"},
- "f8.f8.f7.f1": {"81", "82"},
- "f9": {"9"},
- "f10.0.f10.0.f6": {"101", "102"},
- "f10.0.f10.1.f6": {"103", "104"},
- "f11.0.f11.0.f6": {"111", "112"},
- "f11.0.f11.1.f6": {"113", "114"},
- "f12.0.f12.0.f6": {"121", "122"},
- "f12.0.f12.1.f6": {"123", "124"},
- "f13.0.f13.0.f6": {"131", "132"},
- "f13.0.f13.1.f6": {"133", "134"},
- }
-
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- s := &S1{}
- _ = NewDecoder().Decode(s, v)
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S3 struct {
- F01 bool
- F02 float32
- F03 float64
- F04 int
- F05 int8
- F06 int16
- F07 int32
- F08 int64
- F09 string
- F10 uint
- F11 uint8
- F12 uint16
- F13 uint32
- F14 uint64
-}
-
-func TestDefaultConverters(t *testing.T) {
- v := map[string][]string{
- "F01": {"true"},
- "F02": {"4.2"},
- "F03": {"4.3"},
- "F04": {"-42"},
- "F05": {"-43"},
- "F06": {"-44"},
- "F07": {"-45"},
- "F08": {"-46"},
- "F09": {"foo"},
- "F10": {"42"},
- "F11": {"43"},
- "F12": {"44"},
- "F13": {"45"},
- "F14": {"46"},
- }
- e := S3{
- F01: true,
- F02: 4.2,
- F03: 4.3,
- F04: -42,
- F05: -43,
- F06: -44,
- F07: -45,
- F08: -46,
- F09: "foo",
- F10: 42,
- F11: 43,
- F12: 44,
- F13: 45,
- F14: 46,
- }
- s := &S3{}
- _ = NewDecoder().Decode(s, v)
- if s.F01 != e.F01 {
- t.Errorf("F01: expected %v, got %v", e.F01, s.F01)
- }
- if s.F02 != e.F02 {
- t.Errorf("F02: expected %v, got %v", e.F02, s.F02)
- }
- if s.F03 != e.F03 {
- t.Errorf("F03: expected %v, got %v", e.F03, s.F03)
- }
- if s.F04 != e.F04 {
- t.Errorf("F04: expected %v, got %v", e.F04, s.F04)
- }
- if s.F05 != e.F05 {
- t.Errorf("F05: expected %v, got %v", e.F05, s.F05)
- }
- if s.F06 != e.F06 {
- t.Errorf("F06: expected %v, got %v", e.F06, s.F06)
- }
- if s.F07 != e.F07 {
- t.Errorf("F07: expected %v, got %v", e.F07, s.F07)
- }
- if s.F08 != e.F08 {
- t.Errorf("F08: expected %v, got %v", e.F08, s.F08)
- }
- if s.F09 != e.F09 {
- t.Errorf("F09: expected %v, got %v", e.F09, s.F09)
- }
- if s.F10 != e.F10 {
- t.Errorf("F10: expected %v, got %v", e.F10, s.F10)
- }
- if s.F11 != e.F11 {
- t.Errorf("F11: expected %v, got %v", e.F11, s.F11)
- }
- if s.F12 != e.F12 {
- t.Errorf("F12: expected %v, got %v", e.F12, s.F12)
- }
- if s.F13 != e.F13 {
- t.Errorf("F13: expected %v, got %v", e.F13, s.F13)
- }
- if s.F14 != e.F14 {
- t.Errorf("F14: expected %v, got %v", e.F14, s.F14)
- }
-}
-
-func TestOn(t *testing.T) {
- v := map[string][]string{
- "F01": {"on"},
- }
- s := S3{}
- err := NewDecoder().Decode(&s, v)
- if err != nil {
- t.Fatal(err)
- }
- if !s.F01 {
- t.Fatal("Value was not set to true")
- }
-}
-
-// ----------------------------------------------------------------------------
-
-func TestInlineStruct(t *testing.T) {
- s1 := &struct {
- F01 bool
- }{}
- s2 := &struct {
- F01 int
- }{}
- v1 := map[string][]string{
- "F01": {"true"},
- }
- v2 := map[string][]string{
- "F01": {"42"},
- }
- decoder := NewDecoder()
- _ = decoder.Decode(s1, v1)
- if s1.F01 != true {
- t.Errorf("s1: expected %v, got %v", true, s1.F01)
- }
- _ = decoder.Decode(s2, v2)
- if s2.F01 != 42 {
- t.Errorf("s2: expected %v, got %v", 42, s2.F01)
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type Foo struct {
- F01 int
- F02 Bar
- Bif []Baz
-}
-
-type Bar struct {
- F01 string
- F02 string
- F03 string
- F14 string
- S05 string
- Str string
-}
-
-type Baz struct {
- F99 []string
-}
-
-func TestSimpleExample(t *testing.T) {
- data := map[string][]string{
- "F01": {"1"},
- "F02.F01": {"S1"},
- "F02.F02": {"S2"},
- "F02.F03": {"S3"},
- "F02.F14": {"S4"},
- "F02.S05": {"S5"},
- "F02.Str": {"Str"},
- "Bif.0.F99": {"A", "B", "C"},
- }
-
- e := &Foo{
- F01: 1,
- F02: Bar{
- F01: "S1",
- F02: "S2",
- F03: "S3",
- F14: "S4",
- S05: "S5",
- Str: "Str",
- },
- Bif: []Baz{{
- F99: []string{"A", "B", "C"}},
- },
- }
-
- s := &Foo{}
- _ = NewDecoder().Decode(s, data)
-
- if s.F01 != e.F01 {
- t.Errorf("F01: expected %v, got %v", e.F01, s.F01)
- }
- if s.F02.F01 != e.F02.F01 {
- t.Errorf("F02.F01: expected %v, got %v", e.F02.F01, s.F02.F01)
- }
- if s.F02.F02 != e.F02.F02 {
- t.Errorf("F02.F02: expected %v, got %v", e.F02.F02, s.F02.F02)
- }
- if s.F02.F03 != e.F02.F03 {
- t.Errorf("F02.F03: expected %v, got %v", e.F02.F03, s.F02.F03)
- }
- if s.F02.F14 != e.F02.F14 {
- t.Errorf("F02.F14: expected %v, got %v", e.F02.F14, s.F02.F14)
- }
- if s.F02.S05 != e.F02.S05 {
- t.Errorf("F02.S05: expected %v, got %v", e.F02.S05, s.F02.S05)
- }
- if s.F02.Str != e.F02.Str {
- t.Errorf("F02.Str: expected %v, got %v", e.F02.Str, s.F02.Str)
- }
- if len(s.Bif) != len(e.Bif) {
- t.Errorf("Bif len: expected %d, got %d", len(e.Bif), len(s.Bif))
- } else {
- if len(s.Bif[0].F99) != len(e.Bif[0].F99) {
- t.Errorf("Bif[0].F99 len: expected %d, got %d", len(e.Bif[0].F99), len(s.Bif[0].F99))
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S4 struct {
- F01 int64
- F02 float64
- F03 bool
- F04 rudeBool
-}
-
-func TestConversionError(t *testing.T) {
- data := map[string][]string{
- "F01": {"foo"},
- "F02": {"bar"},
- "F03": {"baz"},
- "F04": {"not-a-yes-or-nope"},
- }
- s := &S4{}
- e := NewDecoder().Decode(s, data)
-
- m := e.(MultiError)
- if len(m) != 4 {
- t.Errorf("Expected 3 errors, got %v", m)
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S5 struct {
- F01 []string
-}
-
-func TestEmptyValue(t *testing.T) {
- data := map[string][]string{
- "F01": {"", "foo"},
- }
- s := &S5{}
- NewDecoder().Decode(s, data)
- if len(s.F01) != 1 {
- t.Errorf("Expected 1 values in F01")
- }
-}
-
-func TestEmptyValueZeroEmpty(t *testing.T) {
- data := map[string][]string{
- "F01": {"", "foo"},
- }
- s := S5{}
- d := NewDecoder()
- d.ZeroEmpty(true)
- err := d.Decode(&s, data)
- if err != nil {
- t.Fatal(err)
- }
- if len(s.F01) != 2 {
- t.Errorf("Expected 1 values in F01")
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S6 struct {
- id string
-}
-
-func TestUnexportedField(t *testing.T) {
- data := map[string][]string{
- "id": {"identifier"},
- }
- s := &S6{}
- NewDecoder().Decode(s, data)
- if s.id != "" {
- t.Errorf("Unexported field expected to be ignored")
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S7 struct {
- ID string
-}
-
-func TestMultipleValues(t *testing.T) {
- data := map[string][]string{
- "ID": {"0", "1"},
- }
-
- s := S7{}
- NewDecoder().Decode(&s, data)
- if s.ID != "1" {
- t.Errorf("Last defined value must be used when multiple values for same field are provided")
- }
-}
-
-type S8 struct {
- ID string `json:"id"`
-}
-
-func TestSetAliasTag(t *testing.T) {
- data := map[string][]string{
- "id": {"foo"},
- }
-
- s := S8{}
- dec := NewDecoder()
- dec.SetAliasTag("json")
- dec.Decode(&s, data)
- if s.ID != "foo" {
- t.Fatalf("Bad value: got %q, want %q", s.ID, "foo")
- }
-}
-
-func TestZeroEmpty(t *testing.T) {
- data := map[string][]string{
- "F01": {""},
- "F03": {"true"},
- }
- s := S4{1, 1, false, false}
- d := NewDecoder()
- d.ZeroEmpty(true)
-
- err := d.Decode(&s, data)
- if err != nil {
- t.Fatal(err)
- }
- if s.F01 != 0 {
- t.Errorf("F01: got %v, want %v", s.F01, 0)
- }
- if s.F02 != 1 {
- t.Errorf("F02: got %v, want %v", s.F02, 1)
- }
- if s.F03 != true {
- t.Errorf("F03: got %v, want %v", s.F03, true)
- }
-}
-
-func TestNoZeroEmpty(t *testing.T) {
- data := map[string][]string{
- "F01": {""},
- "F03": {"true"},
- }
- s := S4{1, 1, false, false}
- d := NewDecoder()
- d.ZeroEmpty(false)
- err := d.Decode(&s, data)
- if err != nil {
- t.Fatal(err)
- }
- if s.F01 != 1 {
- t.Errorf("F01: got %v, want %v", s.F01, 1)
- }
- if s.F02 != 1 {
- t.Errorf("F02: got %v, want %v", s.F02, 1)
- }
- if s.F03 != true {
- t.Errorf("F03: got %v, want %v", s.F03, true)
- }
- if s.F04 != false {
- t.Errorf("F04: got %v, want %v", s.F04, false)
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S9 struct {
- Id string
-}
-
-type S10 struct {
- S9
-}
-
-func TestEmbeddedField(t *testing.T) {
- data := map[string][]string{
- "Id": {"identifier"},
- }
- s := &S10{}
- NewDecoder().Decode(s, data)
- if s.Id != "identifier" {
- t.Errorf("Missing support for embedded fields")
- }
-}
-
-type S11 struct {
- S10
-}
-
-func TestMultipleLevelEmbeddedField(t *testing.T) {
- data := map[string][]string{
- "Id": {"identifier"},
- }
- s := &S11{}
- err := NewDecoder().Decode(s, data)
- if s.Id != "identifier" {
- t.Errorf("Missing support for multiple-level embedded fields (%v)", err)
- }
-}
-
-func TestInvalidPath(t *testing.T) {
- data := map[string][]string{
- "Foo.Bar": {"baz"},
- }
- s := S9{}
- err := NewDecoder().Decode(&s, data)
- expectedErr := `schema: invalid path "Foo.Bar"`
- if err.Error() != expectedErr {
- t.Fatalf("got %q, want %q", err, expectedErr)
- }
-}
-
-func TestInvalidPathIgnoreUnknownKeys(t *testing.T) {
- data := map[string][]string{
- "Foo.Bar": {"baz"},
- }
- s := S9{}
- dec := NewDecoder()
- dec.IgnoreUnknownKeys(true)
- err := dec.Decode(&s, data)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S1NT struct {
- F1 int
- F2 *int
- F3 []int
- F4 []*int
- F5 *[]int
- F6 *[]*int
- F7 S2
- F8 *S1
- F9 int `schema:"-"`
- F10 []S1
- F11 []*S1
- F12 *[]S1
- F13 *[]*S1
-}
-
-func TestAllNT(t *testing.T) {
- v := map[string][]string{
- "f1": {"1"},
- "f2": {"2"},
- "f3": {"31", "32"},
- "f4": {"41", "42"},
- "f5": {"51", "52"},
- "f6": {"61", "62"},
- "f7.f1": {"71", "72"},
- "f8.f8.f7.f1": {"81", "82"},
- "f9": {"9"},
- "f10.0.f10.0.f6": {"101", "102"},
- "f10.0.f10.1.f6": {"103", "104"},
- "f11.0.f11.0.f6": {"111", "112"},
- "f11.0.f11.1.f6": {"113", "114"},
- "f12.0.f12.0.f6": {"121", "122"},
- "f12.0.f12.1.f6": {"123", "124"},
- "f13.0.f13.0.f6": {"131", "132"},
- "f13.0.f13.1.f6": {"133", "134"},
- }
- f2 := 2
- f41, f42 := 41, 42
- f61, f62 := 61, 62
- f71, f72 := 71, 72
- f81, f82 := 81, 82
- f101, f102, f103, f104 := 101, 102, 103, 104
- f111, f112, f113, f114 := 111, 112, 113, 114
- f121, f122, f123, f124 := 121, 122, 123, 124
- f131, f132, f133, f134 := 131, 132, 133, 134
- e := S1NT{
- F1: 1,
- F2: &f2,
- F3: []int{31, 32},
- F4: []*int{&f41, &f42},
- F5: &[]int{51, 52},
- F6: &[]*int{&f61, &f62},
- F7: S2{
- F01: &[]*int{&f71, &f72},
- },
- F8: &S1{
- F08: &S1{
- F07: S2{
- F01: &[]*int{&f81, &f82},
- },
- },
- },
- F9: 0,
- F10: []S1{
- S1{
- F10: []S1{
- S1{F06: &[]*int{&f101, &f102}},
- S1{F06: &[]*int{&f103, &f104}},
- },
- },
- },
- F11: []*S1{
- &S1{
- F11: []*S1{
- &S1{F06: &[]*int{&f111, &f112}},
- &S1{F06: &[]*int{&f113, &f114}},
- },
- },
- },
- F12: &[]S1{
- S1{
- F12: &[]S1{
- S1{F06: &[]*int{&f121, &f122}},
- S1{F06: &[]*int{&f123, &f124}},
- },
- },
- },
- F13: &[]*S1{
- &S1{
- F13: &[]*S1{
- &S1{F06: &[]*int{&f131, &f132}},
- &S1{F06: &[]*int{&f133, &f134}},
- },
- },
- },
- }
-
- s := &S1NT{}
- _ = NewDecoder().Decode(s, v)
-
- vals := func(values []*int) []int {
- r := make([]int, len(values))
- for k, v := range values {
- r[k] = *v
- }
- return r
- }
-
- if s.F1 != e.F1 {
- t.Errorf("f1: expected %v, got %v", e.F1, s.F1)
- }
- if s.F2 == nil {
- t.Errorf("f2: expected %v, got nil", *e.F2)
- } else if *s.F2 != *e.F2 {
- t.Errorf("f2: expected %v, got %v", *e.F2, *s.F2)
- }
- if s.F3 == nil {
- t.Errorf("f3: expected %v, got nil", e.F3)
- } else if len(s.F3) != 2 || s.F3[0] != e.F3[0] || s.F3[1] != e.F3[1] {
- t.Errorf("f3: expected %v, got %v", e.F3, s.F3)
- }
- if s.F4 == nil {
- t.Errorf("f4: expected %v, got nil", e.F4)
- } else {
- if len(s.F4) != 2 || *(s.F4)[0] != *(e.F4)[0] || *(s.F4)[1] != *(e.F4)[1] {
- t.Errorf("f4: expected %v, got %v", vals(e.F4), vals(s.F4))
- }
- }
- if s.F5 == nil {
- t.Errorf("f5: expected %v, got nil", e.F5)
- } else {
- sF5, eF5 := *s.F5, *e.F5
- if len(sF5) != 2 || sF5[0] != eF5[0] || sF5[1] != eF5[1] {
- t.Errorf("f5: expected %v, got %v", eF5, sF5)
- }
- }
- if s.F6 == nil {
- t.Errorf("f6: expected %v, got nil", vals(*e.F6))
- } else {
- sF6, eF6 := *s.F6, *e.F6
- if len(sF6) != 2 || *(sF6)[0] != *(eF6)[0] || *(sF6)[1] != *(eF6)[1] {
- t.Errorf("f6: expected %v, got %v", vals(eF6), vals(sF6))
- }
- }
- if s.F7.F01 == nil {
- t.Errorf("f7.f1: expected %v, got nil", vals(*e.F7.F01))
- } else {
- sF7, eF7 := *s.F7.F01, *e.F7.F01
- if len(sF7) != 2 || *(sF7)[0] != *(eF7)[0] || *(sF7)[1] != *(eF7)[1] {
- t.Errorf("f7.f1: expected %v, got %v", vals(eF7), vals(sF7))
- }
- }
- if s.F8 == nil {
- t.Errorf("f8: got nil")
- } else if s.F8.F08 == nil {
- t.Errorf("f8.f8: got nil")
- } else if s.F8.F08.F07.F01 == nil {
- t.Errorf("f8.f8.f7.f1: expected %v, got nil", vals(*e.F8.F08.F07.F01))
- } else {
- sF8, eF8 := *s.F8.F08.F07.F01, *e.F8.F08.F07.F01
- if len(sF8) != 2 || *(sF8)[0] != *(eF8)[0] || *(sF8)[1] != *(eF8)[1] {
- t.Errorf("f8.f8.f7.f1: expected %v, got %v", vals(eF8), vals(sF8))
- }
- }
- if s.F9 != e.F9 {
- t.Errorf("f9: expected %v, got %v", e.F9, s.F9)
- }
- if s.F10 == nil {
- t.Errorf("f10: got nil")
- } else if len(s.F10) != 1 {
- t.Errorf("f10: expected 1 element, got %v", s.F10)
- } else {
- if len(s.F10[0].F10) != 2 {
- t.Errorf("f10.0.f10: expected 1 element, got %v", s.F10[0].F10)
- } else {
- sF10, eF10 := *s.F10[0].F10[0].F06, *e.F10[0].F10[0].F06
- if sF10 == nil {
- t.Errorf("f10.0.f10.0.f6: expected %v, got nil", vals(eF10))
- } else {
- if len(sF10) != 2 || *(sF10)[0] != *(eF10)[0] || *(sF10)[1] != *(eF10)[1] {
- t.Errorf("f10.0.f10.0.f6: expected %v, got %v", vals(eF10), vals(sF10))
- }
- }
- sF10, eF10 = *s.F10[0].F10[1].F06, *e.F10[0].F10[1].F06
- if sF10 == nil {
- t.Errorf("f10.0.f10.0.f6: expected %v, got nil", vals(eF10))
- } else {
- if len(sF10) != 2 || *(sF10)[0] != *(eF10)[0] || *(sF10)[1] != *(eF10)[1] {
- t.Errorf("f10.0.f10.0.f6: expected %v, got %v", vals(eF10), vals(sF10))
- }
- }
- }
- }
- if s.F11 == nil {
- t.Errorf("f11: got nil")
- } else if len(s.F11) != 1 {
- t.Errorf("f11: expected 1 element, got %v", s.F11)
- } else {
- if len(s.F11[0].F11) != 2 {
- t.Errorf("f11.0.f11: expected 1 element, got %v", s.F11[0].F11)
- } else {
- sF11, eF11 := *s.F11[0].F11[0].F06, *e.F11[0].F11[0].F06
- if sF11 == nil {
- t.Errorf("f11.0.f11.0.f6: expected %v, got nil", vals(eF11))
- } else {
- if len(sF11) != 2 || *(sF11)[0] != *(eF11)[0] || *(sF11)[1] != *(eF11)[1] {
- t.Errorf("f11.0.f11.0.f6: expected %v, got %v", vals(eF11), vals(sF11))
- }
- }
- sF11, eF11 = *s.F11[0].F11[1].F06, *e.F11[0].F11[1].F06
- if sF11 == nil {
- t.Errorf("f11.0.f11.0.f6: expected %v, got nil", vals(eF11))
- } else {
- if len(sF11) != 2 || *(sF11)[0] != *(eF11)[0] || *(sF11)[1] != *(eF11)[1] {
- t.Errorf("f11.0.f11.0.f6: expected %v, got %v", vals(eF11), vals(sF11))
- }
- }
- }
- }
- if s.F12 == nil {
- t.Errorf("f12: got nil")
- } else if len(*s.F12) != 1 {
- t.Errorf("f12: expected 1 element, got %v", *s.F12)
- } else {
- sF12, eF12 := *(s.F12), *(e.F12)
- if len(*sF12[0].F12) != 2 {
- t.Errorf("f12.0.f12: expected 1 element, got %v", *sF12[0].F12)
- } else {
- sF122, eF122 := *(*sF12[0].F12)[0].F06, *(*eF12[0].F12)[0].F06
- if sF122 == nil {
- t.Errorf("f12.0.f12.0.f6: expected %v, got nil", vals(eF122))
- } else {
- if len(sF122) != 2 || *(sF122)[0] != *(eF122)[0] || *(sF122)[1] != *(eF122)[1] {
- t.Errorf("f12.0.f12.0.f6: expected %v, got %v", vals(eF122), vals(sF122))
- }
- }
- sF122, eF122 = *(*sF12[0].F12)[1].F06, *(*eF12[0].F12)[1].F06
- if sF122 == nil {
- t.Errorf("f12.0.f12.0.f6: expected %v, got nil", vals(eF122))
- } else {
- if len(sF122) != 2 || *(sF122)[0] != *(eF122)[0] || *(sF122)[1] != *(eF122)[1] {
- t.Errorf("f12.0.f12.0.f6: expected %v, got %v", vals(eF122), vals(sF122))
- }
- }
- }
- }
- if s.F13 == nil {
- t.Errorf("f13: got nil")
- } else if len(*s.F13) != 1 {
- t.Errorf("f13: expected 1 element, got %v", *s.F13)
- } else {
- sF13, eF13 := *(s.F13), *(e.F13)
- if len(*sF13[0].F13) != 2 {
- t.Errorf("f13.0.f13: expected 1 element, got %v", *sF13[0].F13)
- } else {
- sF132, eF132 := *(*sF13[0].F13)[0].F06, *(*eF13[0].F13)[0].F06
- if sF132 == nil {
- t.Errorf("f13.0.f13.0.f6: expected %v, got nil", vals(eF132))
- } else {
- if len(sF132) != 2 || *(sF132)[0] != *(eF132)[0] || *(sF132)[1] != *(eF132)[1] {
- t.Errorf("f13.0.f13.0.f6: expected %v, got %v", vals(eF132), vals(sF132))
- }
- }
- sF132, eF132 = *(*sF13[0].F13)[1].F06, *(*eF13[0].F13)[1].F06
- if sF132 == nil {
- t.Errorf("f13.0.f13.0.f6: expected %v, got nil", vals(eF132))
- } else {
- if len(sF132) != 2 || *(sF132)[0] != *(eF132)[0] || *(sF132)[1] != *(eF132)[1] {
- t.Errorf("f13.0.f13.0.f6: expected %v, got %v", vals(eF132), vals(sF132))
- }
- }
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S12A struct {
- ID []int
-}
-
-func TestCSVSlice(t *testing.T) {
- data := map[string][]string{
- "ID": {"0,1"},
- }
-
- s := S12A{}
- NewDecoder().Decode(&s, data)
- if len(s.ID) != 2 {
- t.Errorf("Expected two values in the result list, got %+v", s.ID)
- }
- if s.ID[0] != 0 || s.ID[1] != 1 {
- t.Errorf("Expected []{0, 1} got %+v", s)
- }
-}
-
-type S12B struct {
- ID []string
-}
-
-//Decode should not split on , into a slice for string only
-func TestCSVStringSlice(t *testing.T) {
- data := map[string][]string{
- "ID": {"0,1"},
- }
-
- s := S12B{}
- NewDecoder().Decode(&s, data)
- if len(s.ID) != 1 {
- t.Errorf("Expected one value in the result list, got %+v", s.ID)
- }
- if s.ID[0] != "0,1" {
- t.Errorf("Expected []{0, 1} got %+v", s)
- }
-}
-
-//Invalid data provided by client should not panic (github issue 33)
-func TestInvalidDataProvidedByClient(t *testing.T) {
- defer func() {
- if r := recover(); r != nil {
- t.Errorf("Panicked calling decoder.Decode: %v", r)
- }
- }()
-
- type S struct {
- f string
- }
-
- data := map[string][]string{
- "f.f": {"v"},
- }
-
- err := NewDecoder().Decode(new(S), data)
- if err == nil {
- t.Errorf("invalid path in decoder.Decode should return an error.")
- }
-}
-
-// underlying cause of error in issue 33
-func TestInvalidPathInCacheParsePath(t *testing.T) {
- type S struct {
- f string
- }
-
- typ := reflect.ValueOf(new(S)).Elem().Type()
- c := newCache()
- _, err := c.parsePath("f.f", typ)
- if err == nil {
- t.Errorf("invalid path in cache.parsePath should return an error.")
- }
-}
-
-// issue 32
-func TestDecodeToTypedField(t *testing.T) {
- type Aa bool
- s1 := &struct{ Aa }{}
- v1 := map[string][]string{"Aa": {"true"}}
- NewDecoder().Decode(s1, v1)
- if s1.Aa != Aa(true) {
- t.Errorf("s1: expected %v, got %v", true, s1.Aa)
- }
-}
-
-// issue 37
-func TestRegisterConverter(t *testing.T) {
- type Aa int
- type Bb int
- s1 := &struct {
- Aa
- Bb
- }{}
- decoder := NewDecoder()
-
- decoder.RegisterConverter(s1.Aa, func(s string) reflect.Value { return reflect.ValueOf(1) })
- decoder.RegisterConverter(s1.Bb, func(s string) reflect.Value { return reflect.ValueOf(2) })
-
- v1 := map[string][]string{"Aa": {"4"}, "Bb": {"5"}}
- decoder.Decode(s1, v1)
-
- if s1.Aa != Aa(1) {
- t.Errorf("s1.Aa: expected %v, got %v", 1, s1.Aa)
- }
- if s1.Bb != Bb(2) {
- t.Errorf("s1.Bb: expected %v, got %v", 2, s1.Bb)
- }
-}
-
-// Issue #40
-func TestRegisterConverterSlice(t *testing.T) {
- decoder := NewDecoder()
- decoder.RegisterConverter([]string{}, func(input string) reflect.Value {
- return reflect.ValueOf(strings.Split(input, ","))
- })
-
- result := struct {
- Multiple []string `schema:"multiple"`
- }{}
-
- expected := []string{"one", "two", "three"}
- decoder.Decode(&result, map[string][]string{
- "multiple": []string{"one,two,three"},
- })
- for i := range expected {
- if got, want := expected[i], result.Multiple[i]; got != want {
- t.Errorf("%d: got %s, want %s", i, got, want)
- }
- }
-}
-
-func TestRegisterConverterMap(t *testing.T) {
- decoder := NewDecoder()
- decoder.IgnoreUnknownKeys(false)
- decoder.RegisterConverter(map[string]string{}, func(input string) reflect.Value {
- m := make(map[string]string)
- for _, pair := range strings.Split(input, ",") {
- parts := strings.Split(pair, ":")
- switch len(parts) {
- case 2:
- m[parts[0]] = parts[1]
- }
- }
- return reflect.ValueOf(m)
- })
-
- result := struct {
- Multiple map[string]string `schema:"multiple"`
- }{}
-
- err := decoder.Decode(&result, map[string][]string{
- "multiple": []string{"a:one,b:two"},
- })
- if err != nil {
- t.Fatal(err)
- }
- expected := map[string]string{"a": "one", "b": "two"}
- for k, v := range expected {
- got, ok := result.Multiple[k]
- if !ok {
- t.Fatalf("got %v, want %v", result.Multiple, expected)
- }
- if got != v {
- t.Errorf("got %s, want %s", got, v)
- }
- }
-}
-
-type S13 struct {
- Value []S14
-}
-
-type S14 struct {
- F1 string
- F2 string
-}
-
-func (n *S14) UnmarshalText(text []byte) error {
- textParts := strings.Split(string(text), " ")
- if len(textParts) < 2 {
- return errors.New("Not a valid name!")
- }
-
- n.F1, n.F2 = textParts[0], textParts[len(textParts)-1]
- return nil
-}
-
-type S15 struct {
- Value []S16
-}
-
-type S16 struct {
- F1 string
- F2 string
-}
-
-func TestCustomTypeSlice(t *testing.T) {
- data := map[string][]string{
- "Value.0": []string{"Louisa May Alcott"},
- "Value.1": []string{"Florence Nightingale"},
- "Value.2": []string{"Clara Barton"},
- }
-
- s := S13{}
- decoder := NewDecoder()
-
- if err := decoder.Decode(&s, data); err != nil {
- t.Fatal(err)
- }
-
- if len(s.Value) != 3 {
- t.Fatalf("Expected 3 values in the result list, got %+v", s.Value)
- }
- if s.Value[0].F1 != "Louisa" || s.Value[0].F2 != "Alcott" {
- t.Errorf("Expected S14{'Louisa', 'Alcott'} got %+v", s.Value[0])
- }
- if s.Value[1].F1 != "Florence" || s.Value[1].F2 != "Nightingale" {
- t.Errorf("Expected S14{'Florence', 'Nightingale'} got %+v", s.Value[1])
- }
- if s.Value[2].F1 != "Clara" || s.Value[2].F2 != "Barton" {
- t.Errorf("Expected S14{'Clara', 'Barton'} got %+v", s.Value[2])
- }
-}
-
-func TestCustomTypeSliceWithError(t *testing.T) {
- data := map[string][]string{
- "Value.0": []string{"Louisa May Alcott"},
- "Value.1": []string{"Florence Nightingale"},
- "Value.2": []string{"Clara"},
- }
-
- s := S13{}
- decoder := NewDecoder()
-
- if err := decoder.Decode(&s, data); err == nil {
- t.Error("Not detecting error in conversion")
- }
-}
-
-func TestNoTextUnmarshalerTypeSlice(t *testing.T) {
- data := map[string][]string{
- "Value.0": []string{"Louisa May Alcott"},
- "Value.1": []string{"Florence Nightingale"},
- "Value.2": []string{"Clara Barton"},
- }
-
- s := S15{}
- decoder := NewDecoder()
-
- if err := decoder.Decode(&s, data); err == nil {
- t.Error("Not detecting when there's no converter")
- }
-}
-
-// ----------------------------------------------------------------------------
-
-type S17 struct {
- Value S14
-}
-
-type S18 struct {
- Value S16
-}
-
-func TestCustomType(t *testing.T) {
- data := map[string][]string{
- "Value": []string{"Louisa May Alcott"},
- }
-
- s := S17{}
- decoder := NewDecoder()
-
- if err := decoder.Decode(&s, data); err != nil {
- t.Fatal(err)
- }
-
- if s.Value.F1 != "Louisa" || s.Value.F2 != "Alcott" {
- t.Errorf("Expected S14{'Louisa', 'Alcott'} got %+v", s.Value)
- }
-}
-
-func TestCustomTypeWithError(t *testing.T) {
- data := map[string][]string{
- "Value": []string{"Louisa"},
- }
-
- s := S17{}
- decoder := NewDecoder()
-
- if err := decoder.Decode(&s, data); err == nil {
- t.Error("Not detecting error in conversion")
- }
-}
-
-func TestNoTextUnmarshalerType(t *testing.T) {
- data := map[string][]string{
- "Value": []string{"Louisa May Alcott"},
- }
-
- s := S18{}
- decoder := NewDecoder()
-
- if err := decoder.Decode(&s, data); err == nil {
- t.Error("Not detecting when there's no converter")
- }
-}
-
-func TestExpectedType(t *testing.T) {
- data := map[string][]string{
- "bools": []string{"1", "a"},
- "date": []string{"invalid"},
- "Foo.Bar": []string{"a", "b"},
- }
-
- type B struct {
- Bar *int
- }
- type A struct {
- Bools []bool `schema:"bools"`
- Date time.Time `schema:"date"`
- Foo B
- }
-
- a := A{}
-
- err := NewDecoder().Decode(&a, data)
-
- e := err.(MultiError)["bools"].(ConversionError)
- if e.Type != reflect.TypeOf(false) && e.Index == 1 {
- t.Errorf("Expected bool, index: 1 got %+v, index: %d", e.Type, e.Index)
- }
- e = err.(MultiError)["date"].(ConversionError)
- if e.Type != reflect.TypeOf(time.Time{}) {
- t.Errorf("Expected time.Time got %+v", e.Type)
- }
- e = err.(MultiError)["Foo.Bar"].(ConversionError)
- if e.Type != reflect.TypeOf(0) {
- t.Errorf("Expected int got %+v", e.Type)
- }
-}
-
-type R1 struct {
- A string `schema:"a,required"`
- B struct {
- C int `schema:"c,required"`
- D float64 `schema:"d"`
- E string `schema:"e,required"`
- } `schema:"b"`
- F []string `schema:"f,required"`
- G []int `schema:"g,othertag"`
- H bool `schema:"h,required"`
-}
-
-func TestRequiredField(t *testing.T) {
- var a R1
- v := map[string][]string{
- "a": []string{"bbb"},
- "b.c": []string{"88"},
- "b.d": []string{"9"},
- "f": []string{""},
- "h": []string{"true"},
- }
- err := NewDecoder().Decode(&a, v)
- if err == nil {
- t.Errorf("error nil, b.e is empty expect")
- return
- }
- // b.e empty
- v["b.e"] = []string{""} // empty string
- err = NewDecoder().Decode(&a, v)
- if err == nil {
- t.Errorf("error nil, b.e is empty expect")
- return
- }
-
- // all fields ok
- v["b.e"] = []string{"nonempty"}
- err = NewDecoder().Decode(&a, v)
- if err != nil {
- t.Errorf("error: %v", err)
- return
- }
-
- // set f empty
- v["f"] = []string{}
- err = NewDecoder().Decode(&a, v)
- if err == nil {
- t.Errorf("error nil, f is empty expect")
- return
- }
- v["f"] = []string{"nonempty"}
-
- // b.c type int with empty string
- v["b.c"] = []string{""}
- err = NewDecoder().Decode(&a, v)
- if err == nil {
- t.Errorf("error nil, b.c is empty expect")
- return
- }
- v["b.c"] = []string{"3"}
-
- // h type bool with empty string
- v["h"] = []string{""}
- err = NewDecoder().Decode(&a, v)
- if err == nil {
- t.Errorf("error nil, h is empty expect")
- return
- }
-}
-
-type AS1 struct {
- A int32 `schema:"a,required"`
- E int32 `schema:"e,required"`
-}
-type AS2 struct {
- AS1
- B string `schema:"b,required"`
-}
-type AS3 struct {
- C int32 `schema:"c"`
-}
-
-type AS4 struct {
- AS3
- D string `schema:"d"`
-}
-
-func TestAnonymousStructField(t *testing.T) {
- patterns := []map[string][]string{
- {
- "a": {"1"},
- "e": {"2"},
- "b": {"abc"},
- },
- {
- "AS1.a": {"1"},
- "AS1.e": {"2"},
- "b": {"abc"},
- },
- }
- for _, v := range patterns {
- a := AS2{}
- err := NewDecoder().Decode(&a, v)
- if err != nil {
- t.Errorf("Decode failed %s, %#v", err, v)
- continue
- }
- if a.A != 1 {
- t.Errorf("A: expected %v, got %v", 1, a.A)
- }
- if a.E != 2 {
- t.Errorf("E: expected %v, got %v", 2, a.E)
- }
- if a.B != "abc" {
- t.Errorf("B: expected %v, got %v", "abc", a.B)
- }
- if a.AS1.A != 1 {
- t.Errorf("AS1.A: expected %v, got %v", 1, a.AS1.A)
- }
- if a.AS1.E != 2 {
- t.Errorf("AS1.E: expected %v, got %v", 2, a.AS1.E)
- }
- }
- a := AS2{}
- err := NewDecoder().Decode(&a, map[string][]string{
- "e": {"2"},
- "b": {"abc"},
- })
- if err == nil {
- t.Errorf("error nil, a is empty expect")
- }
- patterns = []map[string][]string{
- {
- "c": {"1"},
- "d": {"abc"},
- },
- {
- "AS3.c": {"1"},
- "d": {"abc"},
- },
- }
- for _, v := range patterns {
- a := AS4{}
- err := NewDecoder().Decode(&a, v)
- if err != nil {
- t.Errorf("Decode failed %s, %#v", err, v)
- continue
- }
- if a.C != 1 {
- t.Errorf("C: expected %v, got %v", 1, a.C)
- }
- if a.D != "abc" {
- t.Errorf("D: expected %v, got %v", "abc", a.D)
- }
- if a.AS3.C != 1 {
- t.Errorf("AS3.C: expected %v, got %v", 1, a.AS3.C)
- }
- }
-}
-
-// Test to ensure that a registered converter overrides the default text unmarshaler.
-func TestRegisterConverterOverridesTextUnmarshaler(t *testing.T) {
- type MyTime time.Time
- s1 := &struct {
- MyTime
- }{}
- decoder := NewDecoder()
-
- ts := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
- decoder.RegisterConverter(s1.MyTime, func(s string) reflect.Value { return reflect.ValueOf(ts) })
-
- v1 := map[string][]string{"MyTime": {"4"}, "Bb": {"5"}}
- decoder.Decode(s1, v1)
-
- if s1.MyTime != MyTime(ts) {
- t.Errorf("s1.Aa: expected %v, got %v", ts, s1.MyTime)
- }
-}
-
-type S20E string
-
-func (e *S20E) UnmarshalText(text []byte) error {
- *e = S20E("x")
- return nil
-}
-
-type S20 []S20E
-
-func (s *S20) UnmarshalText(text []byte) error {
- *s = S20{"a", "b", "c"}
- return nil
-}
-
-// Test to ensure that when a custom type based on a slice implements an
-// encoding.TextUnmarshaler interface that it takes precedence over any
-// implementations by its elements.
-func TestTextUnmarshalerTypeSlice(t *testing.T) {
- data := map[string][]string{
- "Value": []string{"a,b,c"},
- }
- s := struct {
- Value S20
- }{}
- decoder := NewDecoder()
- if err := decoder.Decode(&s, data); err != nil {
- t.Error("Error while decoding:", err)
- }
- expected := S20{"a", "b", "c"}
- if !reflect.DeepEqual(expected, s.Value) {
- t.Errorf("Expected %v errors, got %v", expected, s.Value)
- }
-}
diff --git a/vendor/github.com/gorilla/schema/encoder_test.go b/vendor/github.com/gorilla/schema/encoder_test.go
deleted file mode 100644
index ac4cd6137..000000000
--- a/vendor/github.com/gorilla/schema/encoder_test.go
+++ /dev/null
@@ -1,420 +0,0 @@
-package schema
-
-import (
- "fmt"
- "reflect"
- "testing"
-)
-
-type E1 struct {
- F01 int `schema:"f01"`
- F02 int `schema:"-"`
- F03 string `schema:"f03"`
- F04 string `schema:"f04,omitempty"`
- F05 bool `schema:"f05"`
- F06 bool `schema:"f06"`
- F07 *string `schema:"f07"`
- F08 *int8 `schema:"f08"`
- F09 float64 `schema:"f09"`
- F10 func() `schema:"f10"`
- F11 inner
-}
-type inner struct {
- F12 int
-}
-
-func TestFilled(t *testing.T) {
- f07 := "seven"
- var f08 int8 = 8
- s := &E1{
- F01: 1,
- F02: 2,
- F03: "three",
- F04: "four",
- F05: true,
- F06: false,
- F07: &f07,
- F08: &f08,
- F09: 1.618,
- F10: func() {},
- F11: inner{12},
- }
-
- vals := make(map[string][]string)
- errs := NewEncoder().Encode(s, vals)
-
- valExists(t, "f01", "1", vals)
- valNotExists(t, "f02", vals)
- valExists(t, "f03", "three", vals)
- valExists(t, "f05", "true", vals)
- valExists(t, "f06", "false", vals)
- valExists(t, "f07", "seven", vals)
- valExists(t, "f08", "8", vals)
- valExists(t, "f09", "1.618000", vals)
- valExists(t, "F12", "12", vals)
-
- emptyErr := MultiError{}
- if errs.Error() == emptyErr.Error() {
- t.Errorf("Expected error got %v", errs)
- }
-}
-
-type Aa int
-
-type E3 struct {
- F01 bool `schema:"f01"`
- F02 float32 `schema:"f02"`
- F03 float64 `schema:"f03"`
- F04 int `schema:"f04"`
- F05 int8 `schema:"f05"`
- F06 int16 `schema:"f06"`
- F07 int32 `schema:"f07"`
- F08 int64 `schema:"f08"`
- F09 string `schema:"f09"`
- F10 uint `schema:"f10"`
- F11 uint8 `schema:"f11"`
- F12 uint16 `schema:"f12"`
- F13 uint32 `schema:"f13"`
- F14 uint64 `schema:"f14"`
- F15 Aa `schema:"f15"`
-}
-
-// Test compatibility with default decoder types.
-func TestCompat(t *testing.T) {
- src := &E3{
- F01: true,
- F02: 4.2,
- F03: 4.3,
- F04: -42,
- F05: -43,
- F06: -44,
- F07: -45,
- F08: -46,
- F09: "foo",
- F10: 42,
- F11: 43,
- F12: 44,
- F13: 45,
- F14: 46,
- F15: 1,
- }
- dst := &E3{}
-
- vals := make(map[string][]string)
- encoder := NewEncoder()
- decoder := NewDecoder()
-
- encoder.RegisterEncoder(src.F15, func(reflect.Value) string { return "1" })
- decoder.RegisterConverter(src.F15, func(string) reflect.Value { return reflect.ValueOf(1) })
-
- err := encoder.Encode(src, vals)
- if err != nil {
- t.Errorf("Encoder has non-nil error: %v", err)
- }
- err = decoder.Decode(dst, vals)
- if err != nil {
- t.Errorf("Decoder has non-nil error: %v", err)
- }
-
- if *src != *dst {
- t.Errorf("Decoder-Encoder compatibility: expected %v, got %v\n", src, dst)
- }
-}
-
-func TestEmpty(t *testing.T) {
- s := &E1{
- F01: 1,
- F02: 2,
- F03: "three",
- }
-
- estr := "schema: encoder not found for <nil>"
- vals := make(map[string][]string)
- err := NewEncoder().Encode(s, vals)
- if err.Error() != estr {
- t.Errorf("Expected: %s, got %v", estr, err)
- }
-
- valExists(t, "f03", "three", vals)
- valNotExists(t, "f04", vals)
-}
-
-func TestStruct(t *testing.T) {
- estr := "schema: interface must be a struct"
- vals := make(map[string][]string)
- err := NewEncoder().Encode("hello world", vals)
-
- if err.Error() != estr {
- t.Errorf("Expected: %s, got %v", estr, err)
- }
-}
-
-func TestSlices(t *testing.T) {
- type oneAsWord int
- ones := []oneAsWord{1, 2}
- s1 := &struct {
- ones []oneAsWord `schema:"ones"`
- ints []int `schema:"ints"`
- nonempty []int `schema:"nonempty"`
- empty []int `schema:"empty,omitempty"`
- }{ones, []int{1, 1}, []int{}, []int{}}
- vals := make(map[string][]string)
-
- encoder := NewEncoder()
- encoder.RegisterEncoder(ones[0], func(v reflect.Value) string { return "one" })
- err := encoder.Encode(s1, vals)
- if err != nil {
- t.Errorf("Encoder has non-nil error: %v", err)
- }
-
- valsExist(t, "ones", []string{"one", "one"}, vals)
- valsExist(t, "ints", []string{"1", "1"}, vals)
- valsExist(t, "nonempty", []string{}, vals)
- valNotExists(t, "empty", vals)
-}
-
-func TestCompatSlices(t *testing.T) {
- type oneAsWord int
- type s1 struct {
- Ones []oneAsWord `schema:"ones"`
- Ints []int `schema:"ints"`
- }
- ones := []oneAsWord{1, 1}
- src := &s1{ones, []int{1, 1}}
- vals := make(map[string][]string)
- dst := &s1{}
-
- encoder := NewEncoder()
- encoder.RegisterEncoder(ones[0], func(v reflect.Value) string { return "one" })
-
- decoder := NewDecoder()
- decoder.RegisterConverter(ones[0], func(s string) reflect.Value {
- if s == "one" {
- return reflect.ValueOf(1)
- }
- return reflect.ValueOf(2)
- })
-
- err := encoder.Encode(src, vals)
- if err != nil {
- t.Errorf("Encoder has non-nil error: %v", err)
- }
- err = decoder.Decode(dst, vals)
- if err != nil {
- t.Errorf("Dncoder has non-nil error: %v", err)
- }
-
- if len(src.Ints) != len(dst.Ints) || len(src.Ones) != len(src.Ones) {
- t.Fatalf("Expected %v, got %v", src, dst)
- }
-
- for i, v := range src.Ones {
- if dst.Ones[i] != v {
- t.Fatalf("Expected %v, got %v", v, dst.Ones[i])
- }
- }
-
- for i, v := range src.Ints {
- if dst.Ints[i] != v {
- t.Fatalf("Expected %v, got %v", v, dst.Ints[i])
- }
- }
-}
-
-func TestRegisterEncoder(t *testing.T) {
- type oneAsWord int
- type twoAsWord int
- type oneSliceAsWord []int
-
- s1 := &struct {
- oneAsWord
- twoAsWord
- oneSliceAsWord
- }{1, 2, []int{1, 1}}
- v1 := make(map[string][]string)
-
- encoder := NewEncoder()
- encoder.RegisterEncoder(s1.oneAsWord, func(v reflect.Value) string { return "one" })
- encoder.RegisterEncoder(s1.twoAsWord, func(v reflect.Value) string { return "two" })
- encoder.RegisterEncoder(s1.oneSliceAsWord, func(v reflect.Value) string { return "one" })
-
- err := encoder.Encode(s1, v1)
- if err != nil {
- t.Errorf("Encoder has non-nil error: %v", err)
- }
-
- valExists(t, "oneAsWord", "one", v1)
- valExists(t, "twoAsWord", "two", v1)
- valExists(t, "oneSliceAsWord", "one", v1)
-}
-
-func TestEncoderOrder(t *testing.T) {
- type builtinEncoderSimple int
- type builtinEncoderSimpleOverridden int
- type builtinEncoderSlice []int
- type builtinEncoderSliceOverridden []int
- type builtinEncoderStruct struct{ nr int }
- type builtinEncoderStructOverridden struct{ nr int }
-
- s1 := &struct {
- builtinEncoderSimple `schema:"simple"`
- builtinEncoderSimpleOverridden `schema:"simple_overridden"`
- builtinEncoderSlice `schema:"slice"`
- builtinEncoderSliceOverridden `schema:"slice_overridden"`
- builtinEncoderStruct `schema:"struct"`
- builtinEncoderStructOverridden `schema:"struct_overridden"`
- }{
- 1,
- 1,
- []int{2},
- []int{2},
- builtinEncoderStruct{3},
- builtinEncoderStructOverridden{3},
- }
- v1 := make(map[string][]string)
-
- encoder := NewEncoder()
- encoder.RegisterEncoder(s1.builtinEncoderSimpleOverridden, func(v reflect.Value) string { return "one" })
- encoder.RegisterEncoder(s1.builtinEncoderSliceOverridden, func(v reflect.Value) string { return "two" })
- encoder.RegisterEncoder(s1.builtinEncoderStructOverridden, func(v reflect.Value) string { return "three" })
-
- err := encoder.Encode(s1, v1)
- if err != nil {
- t.Errorf("Encoder has non-nil error: %v", err)
- }
-
- valExists(t, "simple", "1", v1)
- valExists(t, "simple_overridden", "one", v1)
- valExists(t, "slice", "2", v1)
- valExists(t, "slice_overridden", "two", v1)
- valExists(t, "nr", "3", v1)
- valExists(t, "struct_overridden", "three", v1)
-}
-
-func valExists(t *testing.T, key string, expect string, result map[string][]string) {
- valsExist(t, key, []string{expect}, result)
-}
-
-func valsExist(t *testing.T, key string, expect []string, result map[string][]string) {
- vals, ok := result[key]
- if !ok {
- t.Fatalf("Key not found. Expected: %s", key)
- }
-
- if len(expect) != len(vals) {
- t.Fatalf("Expected: %v, got: %v", expect, vals)
- }
-
- for i, v := range expect {
- if vals[i] != v {
- t.Fatalf("Unexpected value. Expected: %v, got %v", v, vals[i])
- }
- }
-}
-
-func valNotExists(t *testing.T, key string, result map[string][]string) {
- if val, ok := result[key]; ok {
- t.Error("Key not ommited. Expected: empty; got: " + val[0] + ".")
- }
-}
-
-type E4 struct {
- ID string `json:"id"`
-}
-
-func TestEncoderSetAliasTag(t *testing.T) {
- data := map[string][]string{}
-
- s := E4{
- ID: "foo",
- }
- encoder := NewEncoder()
- encoder.SetAliasTag("json")
- encoder.Encode(&s, data)
- valExists(t, "id", "foo", data)
-}
-
-type E5 struct {
- F01 int `schema:"f01,omitempty"`
- F02 string `schema:"f02,omitempty"`
- F03 *string `schema:"f03,omitempty"`
- F04 *int8 `schema:"f04,omitempty"`
- F05 float64 `schema:"f05,omitempty"`
- F06 E5F06 `schema:"f06,omitempty"`
- F07 E5F06 `schema:"f07,omitempty"`
- F08 []string `schema:"f08,omitempty"`
- F09 []string `schema:"f09,omitempty"`
-}
-
-type E5F06 struct {
- F0601 string `schema:"f0601,omitempty"`
-}
-
-func TestEncoderWithOmitempty(t *testing.T) {
- vals := map[string][]string{}
-
- s := E5{
- F02: "test",
- F07: E5F06{
- F0601: "test",
- },
- F09: []string{"test"},
- }
-
- encoder := NewEncoder()
- encoder.Encode(&s, vals)
-
- valNotExists(t, "f01", vals)
- valExists(t, "f02", "test", vals)
- valNotExists(t, "f03", vals)
- valNotExists(t, "f04", vals)
- valNotExists(t, "f05", vals)
- valNotExists(t, "f06", vals)
- valExists(t, "f0601", "test", vals)
- valNotExists(t, "f08", vals)
- valsExist(t, "f09", []string{"test"}, vals)
-}
-
-type E6 struct {
- F01 *inner
- F02 *inner
- F03 *inner `schema:",omitempty"`
-}
-
-func TestStructPointer(t *testing.T) {
- vals := map[string][]string{}
- s := E6{
- F01: &inner{2},
- }
-
- encoder := NewEncoder()
- encoder.Encode(&s, vals)
- valExists(t, "F12", "2", vals)
- valExists(t, "F02", "null", vals)
- valNotExists(t, "F03", vals)
-}
-
-func TestRegisterEncoderCustomArrayType(t *testing.T) {
- type CustomInt []int
- type S1 struct {
- SomeInts CustomInt `schema:",omitempty"`
- }
-
- ss := []S1{
- {},
- {CustomInt{}},
- {CustomInt{1, 2, 3}},
- }
-
- for s := range ss {
- vals := map[string][]string{}
-
- encoder := NewEncoder()
- encoder.RegisterEncoder(CustomInt{}, func(value reflect.Value) string {
- return fmt.Sprint(value.Interface())
- })
-
- encoder.Encode(s, vals)
- t.Log(vals)
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/.gitignore b/vendor/github.com/gorilla/websocket/.gitignore
index ac710204f..cd3fcd1ef 100644
--- a/vendor/github.com/gorilla/websocket/.gitignore
+++ b/vendor/github.com/gorilla/websocket/.gitignore
@@ -22,4 +22,4 @@ _testmain.go
*.exe
.idea/
-*.iml \ No newline at end of file
+*.iml
diff --git a/vendor/github.com/gorilla/websocket/.travis.yml b/vendor/github.com/gorilla/websocket/.travis.yml
index 9f233f983..1f730470a 100644
--- a/vendor/github.com/gorilla/websocket/.travis.yml
+++ b/vendor/github.com/gorilla/websocket/.travis.yml
@@ -4,11 +4,12 @@ sudo: false
matrix:
include:
- go: 1.4
- - go: 1.5
- - go: 1.6
- - go: 1.7
- - go: 1.8
- - go: 1.9
+ - go: 1.5.x
+ - go: 1.6.x
+ - go: 1.7.x
+ - go: 1.8.x
+ - go: 1.9.x
+ - go: 1.10.x
- go: tip
allow_failures:
- go: tip
diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md
index 33c3d2be3..20e391f86 100644
--- a/vendor/github.com/gorilla/websocket/README.md
+++ b/vendor/github.com/gorilla/websocket/README.md
@@ -51,7 +51,7 @@ subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn
<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
</table>
-Notes:
+Notes:
1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
2. The application can get the type of a received data message by implementing
diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go
index 934e28e96..8e90de27f 100644
--- a/vendor/github.com/gorilla/websocket/client.go
+++ b/vendor/github.com/gorilla/websocket/client.go
@@ -106,9 +106,13 @@ func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
// DefaultDialer is a dialer with all fields set to the default values.
var DefaultDialer = &Dialer{
- Proxy: http.ProxyFromEnvironment,
+ Proxy: http.ProxyFromEnvironment,
+ HandshakeTimeout: 45 * time.Second,
}
+// nilDialer is dialer to use when receiver is nil.
+var nilDialer Dialer = *DefaultDialer
+
// Dial creates a new client connection. Use requestHeader to specify the
// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
// Use the response.Header to get the selected subprotocol
@@ -121,9 +125,7 @@ var DefaultDialer = &Dialer{
func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
if d == nil {
- d = &Dialer{
- Proxy: http.ProxyFromEnvironment,
- }
+ d = &nilDialer
}
challengeKey, err := generateChallengeKey()
@@ -191,6 +193,8 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
k == "Sec-Websocket-Extensions" ||
(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
+ case k == "Sec-Websocket-Protocol":
+ req.Header["Sec-WebSocket-Protocol"] = vs
default:
req.Header[k] = vs
}
diff --git a/vendor/github.com/gorilla/websocket/client_server_test.go b/vendor/github.com/gorilla/websocket/client_server_test.go
deleted file mode 100644
index 50063b7e0..000000000
--- a/vendor/github.com/gorilla/websocket/client_server_test.go
+++ /dev/null
@@ -1,602 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 websocket
-
-import (
- "bytes"
- "crypto/tls"
- "crypto/x509"
- "encoding/base64"
- "encoding/binary"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "net/http/cookiejar"
- "net/http/httptest"
- "net/url"
- "reflect"
- "strings"
- "testing"
- "time"
-)
-
-var cstUpgrader = Upgrader{
- Subprotocols: []string{"p0", "p1"},
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- EnableCompression: true,
- Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {
- http.Error(w, reason.Error(), status)
- },
-}
-
-var cstDialer = Dialer{
- Subprotocols: []string{"p1", "p2"},
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- HandshakeTimeout: 30 * time.Second,
-}
-
-type cstHandler struct{ *testing.T }
-
-type cstServer struct {
- *httptest.Server
- URL string
-}
-
-const (
- cstPath = "/a/b"
- cstRawQuery = "x=y"
- cstRequestURI = cstPath + "?" + cstRawQuery
-)
-
-func newServer(t *testing.T) *cstServer {
- var s cstServer
- s.Server = httptest.NewServer(cstHandler{t})
- s.Server.URL += cstRequestURI
- s.URL = makeWsProto(s.Server.URL)
- return &s
-}
-
-func newTLSServer(t *testing.T) *cstServer {
- var s cstServer
- s.Server = httptest.NewTLSServer(cstHandler{t})
- s.Server.URL += cstRequestURI
- s.URL = makeWsProto(s.Server.URL)
- return &s
-}
-
-func (t cstHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != cstPath {
- t.Logf("path=%v, want %v", r.URL.Path, cstPath)
- http.Error(w, "bad path", 400)
- return
- }
- if r.URL.RawQuery != cstRawQuery {
- t.Logf("query=%v, want %v", r.URL.RawQuery, cstRawQuery)
- http.Error(w, "bad path", 400)
- return
- }
- subprotos := Subprotocols(r)
- if !reflect.DeepEqual(subprotos, cstDialer.Subprotocols) {
- t.Logf("subprotols=%v, want %v", subprotos, cstDialer.Subprotocols)
- http.Error(w, "bad protocol", 400)
- return
- }
- ws, err := cstUpgrader.Upgrade(w, r, http.Header{"Set-Cookie": {"sessionID=1234"}})
- if err != nil {
- t.Logf("Upgrade: %v", err)
- return
- }
- defer ws.Close()
-
- if ws.Subprotocol() != "p1" {
- t.Logf("Subprotocol() = %s, want p1", ws.Subprotocol())
- ws.Close()
- return
- }
- op, rd, err := ws.NextReader()
- if err != nil {
- t.Logf("NextReader: %v", err)
- return
- }
- wr, err := ws.NextWriter(op)
- if err != nil {
- t.Logf("NextWriter: %v", err)
- return
- }
- if _, err = io.Copy(wr, rd); err != nil {
- t.Logf("NextWriter: %v", err)
- return
- }
- if err := wr.Close(); err != nil {
- t.Logf("Close: %v", err)
- return
- }
-}
-
-func makeWsProto(s string) string {
- return "ws" + strings.TrimPrefix(s, "http")
-}
-
-func sendRecv(t *testing.T, ws *Conn) {
- const message = "Hello World!"
- if err := ws.SetWriteDeadline(time.Now().Add(time.Second)); err != nil {
- t.Fatalf("SetWriteDeadline: %v", err)
- }
- if err := ws.WriteMessage(TextMessage, []byte(message)); err != nil {
- t.Fatalf("WriteMessage: %v", err)
- }
- if err := ws.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
- t.Fatalf("SetReadDeadline: %v", err)
- }
- _, p, err := ws.ReadMessage()
- if err != nil {
- t.Fatalf("ReadMessage: %v", err)
- }
- if string(p) != message {
- t.Fatalf("message=%s, want %s", p, message)
- }
-}
-
-func TestProxyDial(t *testing.T) {
-
- s := newServer(t)
- defer s.Close()
-
- surl, _ := url.Parse(s.Server.URL)
-
- cstDialer := cstDialer // make local copy for modification on next line.
- cstDialer.Proxy = http.ProxyURL(surl)
-
- connect := false
- origHandler := s.Server.Config.Handler
-
- // Capture the request Host header.
- s.Server.Config.Handler = http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "CONNECT" {
- connect = true
- w.WriteHeader(200)
- return
- }
-
- if !connect {
- t.Log("connect not received")
- http.Error(w, "connect not received", 405)
- return
- }
- origHandler.ServeHTTP(w, r)
- })
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestProxyAuthorizationDial(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- surl, _ := url.Parse(s.Server.URL)
- surl.User = url.UserPassword("username", "password")
-
- cstDialer := cstDialer // make local copy for modification on next line.
- cstDialer.Proxy = http.ProxyURL(surl)
-
- connect := false
- origHandler := s.Server.Config.Handler
-
- // Capture the request Host header.
- s.Server.Config.Handler = http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- proxyAuth := r.Header.Get("Proxy-Authorization")
- expectedProxyAuth := "Basic " + base64.StdEncoding.EncodeToString([]byte("username:password"))
- if r.Method == "CONNECT" && proxyAuth == expectedProxyAuth {
- connect = true
- w.WriteHeader(200)
- return
- }
-
- if !connect {
- t.Log("connect with proxy authorization not received")
- http.Error(w, "connect with proxy authorization not received", 405)
- return
- }
- origHandler.ServeHTTP(w, r)
- })
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestDial(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestDialCookieJar(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- jar, _ := cookiejar.New(nil)
- d := cstDialer
- d.Jar = jar
-
- u, _ := url.Parse(s.URL)
-
- switch u.Scheme {
- case "ws":
- u.Scheme = "http"
- case "wss":
- u.Scheme = "https"
- }
-
- cookies := []*http.Cookie{{Name: "gorilla", Value: "ws", Path: "/"}}
- d.Jar.SetCookies(u, cookies)
-
- ws, _, err := d.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
-
- var gorilla string
- var sessionID string
- for _, c := range d.Jar.Cookies(u) {
- if c.Name == "gorilla" {
- gorilla = c.Value
- }
-
- if c.Name == "sessionID" {
- sessionID = c.Value
- }
- }
- if gorilla != "ws" {
- t.Error("Cookie not present in jar.")
- }
-
- if sessionID != "1234" {
- t.Error("Set-Cookie not received from the server.")
- }
-
- sendRecv(t, ws)
-}
-
-func TestDialTLS(t *testing.T) {
- s := newTLSServer(t)
- defer s.Close()
-
- certs := x509.NewCertPool()
- for _, c := range s.TLS.Certificates {
- roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
- if err != nil {
- t.Fatalf("error parsing server's root cert: %v", err)
- }
- for _, root := range roots {
- certs.AddCert(root)
- }
- }
-
- d := cstDialer
- d.TLSClientConfig = &tls.Config{RootCAs: certs}
- ws, _, err := d.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func xTestDialTLSBadCert(t *testing.T) {
- // This test is deactivated because of noisy logging from the net/http package.
- s := newTLSServer(t)
- defer s.Close()
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-}
-
-func TestDialTLSNoVerify(t *testing.T) {
- s := newTLSServer(t)
- defer s.Close()
-
- d := cstDialer
- d.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
- ws, _, err := d.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestDialTimeout(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- d := cstDialer
- d.HandshakeTimeout = -1
- ws, _, err := d.Dial(s.URL, nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-}
-
-func TestDialBadScheme(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, _, err := cstDialer.Dial(s.Server.URL, nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-}
-
-func TestDialBadOrigin(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {"bad"}})
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
- if resp == nil {
- t.Fatalf("resp=nil, err=%v", err)
- }
- if resp.StatusCode != http.StatusForbidden {
- t.Fatalf("status=%d, want %d", resp.StatusCode, http.StatusForbidden)
- }
-}
-
-func TestDialBadHeader(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- for _, k := range []string{"Upgrade",
- "Connection",
- "Sec-Websocket-Key",
- "Sec-Websocket-Version",
- "Sec-Websocket-Protocol"} {
- h := http.Header{}
- h.Set(k, "bad")
- ws, _, err := cstDialer.Dial(s.URL, http.Header{"Origin": {"bad"}})
- if err == nil {
- ws.Close()
- t.Errorf("Dial with header %s returned nil", k)
- }
- }
-}
-
-func TestBadMethod(t *testing.T) {
- s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- ws, err := cstUpgrader.Upgrade(w, r, nil)
- if err == nil {
- t.Errorf("handshake succeeded, expect fail")
- ws.Close()
- }
- }))
- defer s.Close()
-
- req, err := http.NewRequest("POST", s.URL, strings.NewReader(""))
- if err != nil {
- t.Fatalf("NewRequest returned error %v", err)
- }
- req.Header.Set("Connection", "upgrade")
- req.Header.Set("Upgrade", "websocket")
- req.Header.Set("Sec-Websocket-Version", "13")
-
- resp, err := http.DefaultClient.Do(req)
- if err != nil {
- t.Fatalf("Do returned error %v", err)
- }
- resp.Body.Close()
- if resp.StatusCode != http.StatusMethodNotAllowed {
- t.Errorf("Status = %d, want %d", resp.StatusCode, http.StatusMethodNotAllowed)
- }
-}
-
-func TestHandshake(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {s.URL}})
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
-
- var sessionID string
- for _, c := range resp.Cookies() {
- if c.Name == "sessionID" {
- sessionID = c.Value
- }
- }
- if sessionID != "1234" {
- t.Error("Set-Cookie not received from the server.")
- }
-
- if ws.Subprotocol() != "p1" {
- t.Errorf("ws.Subprotocol() = %s, want p1", ws.Subprotocol())
- }
- sendRecv(t, ws)
-}
-
-func TestRespOnBadHandshake(t *testing.T) {
- const expectedStatus = http.StatusGone
- const expectedBody = "This is the response body."
-
- s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(expectedStatus)
- io.WriteString(w, expectedBody)
- }))
- defer s.Close()
-
- ws, resp, err := cstDialer.Dial(makeWsProto(s.URL), nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-
- if resp == nil {
- t.Fatalf("resp=nil, err=%v", err)
- }
-
- if resp.StatusCode != expectedStatus {
- t.Errorf("resp.StatusCode=%d, want %d", resp.StatusCode, expectedStatus)
- }
-
- p, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- t.Fatalf("ReadFull(resp.Body) returned error %v", err)
- }
-
- if string(p) != expectedBody {
- t.Errorf("resp.Body=%s, want %s", p, expectedBody)
- }
-}
-
-// TestHostHeader confirms that the host header provided in the call to Dial is
-// sent to the server.
-func TestHostHeader(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- specifiedHost := make(chan string, 1)
- origHandler := s.Server.Config.Handler
-
- // Capture the request Host header.
- s.Server.Config.Handler = http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- specifiedHost <- r.Host
- origHandler.ServeHTTP(w, r)
- })
-
- ws, _, err := cstDialer.Dial(s.URL, http.Header{"Host": {"testhost"}})
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
-
- if gotHost := <-specifiedHost; gotHost != "testhost" {
- t.Fatalf("gotHost = %q, want \"testhost\"", gotHost)
- }
-
- sendRecv(t, ws)
-}
-
-func TestDialCompression(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- dialer := cstDialer
- dialer.EnableCompression = true
- ws, _, err := dialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestSocksProxyDial(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- proxyListener, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatalf("listen failed: %v", err)
- }
- defer proxyListener.Close()
- go func() {
- c1, err := proxyListener.Accept()
- if err != nil {
- t.Errorf("proxy accept failed: %v", err)
- return
- }
- defer c1.Close()
-
- c1.SetDeadline(time.Now().Add(30 * time.Second))
-
- buf := make([]byte, 32)
- if _, err := io.ReadFull(c1, buf[:3]); err != nil {
- t.Errorf("read failed: %v", err)
- return
- }
- if want := []byte{5, 1, 0}; !bytes.Equal(want, buf[:len(want)]) {
- t.Errorf("read %x, want %x", buf[:len(want)], want)
- }
- if _, err := c1.Write([]byte{5, 0}); err != nil {
- t.Errorf("write failed: %v", err)
- return
- }
- if _, err := io.ReadFull(c1, buf[:10]); err != nil {
- t.Errorf("read failed: %v", err)
- return
- }
- if want := []byte{5, 1, 0, 1}; !bytes.Equal(want, buf[:len(want)]) {
- t.Errorf("read %x, want %x", buf[:len(want)], want)
- return
- }
- buf[1] = 0
- if _, err := c1.Write(buf[:10]); err != nil {
- t.Errorf("write failed: %v", err)
- return
- }
-
- ip := net.IP(buf[4:8])
- port := binary.BigEndian.Uint16(buf[8:10])
-
- c2, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: int(port)})
- if err != nil {
- t.Errorf("dial failed; %v", err)
- return
- }
- defer c2.Close()
- done := make(chan struct{})
- go func() {
- io.Copy(c1, c2)
- close(done)
- }()
- io.Copy(c2, c1)
- <-done
- }()
-
- purl, err := url.Parse("socks5://" + proxyListener.Addr().String())
- if err != nil {
- t.Fatalf("parse failed: %v", err)
- }
-
- cstDialer := cstDialer // make local copy for modification on next line.
- cstDialer.Proxy = http.ProxyURL(purl)
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
diff --git a/vendor/github.com/gorilla/websocket/client_test.go b/vendor/github.com/gorilla/websocket/client_test.go
deleted file mode 100644
index 5aa27b37d..000000000
--- a/vendor/github.com/gorilla/websocket/client_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 The Gorilla WebSocket 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 websocket
-
-import (
- "net/url"
- "testing"
-)
-
-var hostPortNoPortTests = []struct {
- u *url.URL
- hostPort, hostNoPort string
-}{
- {&url.URL{Scheme: "ws", Host: "example.com"}, "example.com:80", "example.com"},
- {&url.URL{Scheme: "wss", Host: "example.com"}, "example.com:443", "example.com"},
- {&url.URL{Scheme: "ws", Host: "example.com:7777"}, "example.com:7777", "example.com"},
- {&url.URL{Scheme: "wss", Host: "example.com:7777"}, "example.com:7777", "example.com"},
-}
-
-func TestHostPortNoPort(t *testing.T) {
- for _, tt := range hostPortNoPortTests {
- hostPort, hostNoPort := hostPortNoPort(tt.u)
- if hostPort != tt.hostPort {
- t.Errorf("hostPortNoPort(%v) returned hostPort %q, want %q", tt.u, hostPort, tt.hostPort)
- }
- if hostNoPort != tt.hostNoPort {
- t.Errorf("hostPortNoPort(%v) returned hostNoPort %q, want %q", tt.u, hostNoPort, tt.hostNoPort)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/compression_test.go b/vendor/github.com/gorilla/websocket/compression_test.go
deleted file mode 100644
index 659cf4215..000000000
--- a/vendor/github.com/gorilla/websocket/compression_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package websocket
-
-import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "testing"
-)
-
-type nopCloser struct{ io.Writer }
-
-func (nopCloser) Close() error { return nil }
-
-func TestTruncWriter(t *testing.T) {
- const data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijlkmnopqrstuvwxyz987654321"
- for n := 1; n <= 10; n++ {
- var b bytes.Buffer
- w := &truncWriter{w: nopCloser{&b}}
- p := []byte(data)
- for len(p) > 0 {
- m := len(p)
- if m > n {
- m = n
- }
- w.Write(p[:m])
- p = p[m:]
- }
- if b.String() != data[:len(data)-len(w.p)] {
- t.Errorf("%d: %q", n, b.String())
- }
- }
-}
-
-func textMessages(num int) [][]byte {
- messages := make([][]byte, num)
- for i := 0; i < num; i++ {
- msg := fmt.Sprintf("planet: %d, country: %d, city: %d, street: %d", i, i, i, i)
- messages[i] = []byte(msg)
- }
- return messages
-}
-
-func BenchmarkWriteNoCompression(b *testing.B) {
- w := ioutil.Discard
- c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024)
- messages := textMessages(100)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- c.WriteMessage(TextMessage, messages[i%len(messages)])
- }
- b.ReportAllocs()
-}
-
-func BenchmarkWriteWithCompression(b *testing.B) {
- w := ioutil.Discard
- c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024)
- messages := textMessages(100)
- c.enableWriteCompression = true
- c.newCompressionWriter = compressNoContextTakeover
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- c.WriteMessage(TextMessage, messages[i%len(messages)])
- }
- b.ReportAllocs()
-}
-
-func TestValidCompressionLevel(t *testing.T) {
- c := newConn(fakeNetConn{}, false, 1024, 1024)
- for _, level := range []int{minCompressionLevel - 1, maxCompressionLevel + 1} {
- if err := c.SetCompressionLevel(level); err == nil {
- t.Errorf("no error for level %d", level)
- }
- }
- for _, level := range []int{minCompressionLevel, maxCompressionLevel} {
- if err := c.SetCompressionLevel(level); err != nil {
- t.Errorf("error for level %d", level)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go
index b051e9591..5f46bf4a5 100644
--- a/vendor/github.com/gorilla/websocket/conn.go
+++ b/vendor/github.com/gorilla/websocket/conn.go
@@ -370,7 +370,7 @@ func (c *Conn) writeFatal(err error) error {
return err
}
-func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
+func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {
<-c.mu
defer func() { c.mu <- true }()
@@ -382,15 +382,14 @@ func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
}
c.conn.SetWriteDeadline(deadline)
- for _, buf := range bufs {
- if len(buf) > 0 {
- _, err := c.conn.Write(buf)
- if err != nil {
- return c.writeFatal(err)
- }
- }
+ if len(buf1) == 0 {
+ _, err = c.conn.Write(buf0)
+ } else {
+ err = c.writeBufs(buf0, buf1)
+ }
+ if err != nil {
+ return c.writeFatal(err)
}
-
if frameType == CloseMessage {
c.writeFatal(ErrCloseSent)
}
diff --git a/vendor/github.com/gorilla/websocket/conn_broadcast_test.go b/vendor/github.com/gorilla/websocket/conn_broadcast_test.go
deleted file mode 100644
index 45038e488..000000000
--- a/vendor/github.com/gorilla/websocket/conn_broadcast_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7
-
-package websocket
-
-import (
- "io"
- "io/ioutil"
- "sync/atomic"
- "testing"
-)
-
-// broadcastBench allows to run broadcast benchmarks.
-// In every broadcast benchmark we create many connections, then send the same
-// message into every connection and wait for all writes complete. This emulates
-// an application where many connections listen to the same data - i.e. PUB/SUB
-// scenarios with many subscribers in one channel.
-type broadcastBench struct {
- w io.Writer
- message *broadcastMessage
- closeCh chan struct{}
- doneCh chan struct{}
- count int32
- conns []*broadcastConn
- compression bool
- usePrepared bool
-}
-
-type broadcastMessage struct {
- payload []byte
- prepared *PreparedMessage
-}
-
-type broadcastConn struct {
- conn *Conn
- msgCh chan *broadcastMessage
-}
-
-func newBroadcastConn(c *Conn) *broadcastConn {
- return &broadcastConn{
- conn: c,
- msgCh: make(chan *broadcastMessage, 1),
- }
-}
-
-func newBroadcastBench(usePrepared, compression bool) *broadcastBench {
- bench := &broadcastBench{
- w: ioutil.Discard,
- doneCh: make(chan struct{}),
- closeCh: make(chan struct{}),
- usePrepared: usePrepared,
- compression: compression,
- }
- msg := &broadcastMessage{
- payload: textMessages(1)[0],
- }
- if usePrepared {
- pm, _ := NewPreparedMessage(TextMessage, msg.payload)
- msg.prepared = pm
- }
- bench.message = msg
- bench.makeConns(10000)
- return bench
-}
-
-func (b *broadcastBench) makeConns(numConns int) {
- conns := make([]*broadcastConn, numConns)
-
- for i := 0; i < numConns; i++ {
- c := newConn(fakeNetConn{Reader: nil, Writer: b.w}, true, 1024, 1024)
- if b.compression {
- c.enableWriteCompression = true
- c.newCompressionWriter = compressNoContextTakeover
- }
- conns[i] = newBroadcastConn(c)
- go func(c *broadcastConn) {
- for {
- select {
- case msg := <-c.msgCh:
- if b.usePrepared {
- c.conn.WritePreparedMessage(msg.prepared)
- } else {
- c.conn.WriteMessage(TextMessage, msg.payload)
- }
- val := atomic.AddInt32(&b.count, 1)
- if val%int32(numConns) == 0 {
- b.doneCh <- struct{}{}
- }
- case <-b.closeCh:
- return
- }
- }
- }(conns[i])
- }
- b.conns = conns
-}
-
-func (b *broadcastBench) close() {
- close(b.closeCh)
-}
-
-func (b *broadcastBench) runOnce() {
- for _, c := range b.conns {
- c.msgCh <- b.message
- }
- <-b.doneCh
-}
-
-func BenchmarkBroadcast(b *testing.B) {
- benchmarks := []struct {
- name string
- usePrepared bool
- compression bool
- }{
- {"NoCompression", false, false},
- {"WithCompression", false, true},
- {"NoCompressionPrepared", true, false},
- {"WithCompressionPrepared", true, true},
- }
- for _, bm := range benchmarks {
- b.Run(bm.name, func(b *testing.B) {
- bench := newBroadcastBench(bm.usePrepared, bm.compression)
- defer bench.close()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- bench.runOnce()
- }
- b.ReportAllocs()
- })
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/conn_test.go b/vendor/github.com/gorilla/websocket/conn_test.go
deleted file mode 100644
index 5fda7b5ca..000000000
--- a/vendor/github.com/gorilla/websocket/conn_test.go
+++ /dev/null
@@ -1,496 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 websocket
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "reflect"
- "testing"
- "testing/iotest"
- "time"
-)
-
-var _ net.Error = errWriteTimeout
-
-type fakeNetConn struct {
- io.Reader
- io.Writer
-}
-
-func (c fakeNetConn) Close() error { return nil }
-func (c fakeNetConn) LocalAddr() net.Addr { return localAddr }
-func (c fakeNetConn) RemoteAddr() net.Addr { return remoteAddr }
-func (c fakeNetConn) SetDeadline(t time.Time) error { return nil }
-func (c fakeNetConn) SetReadDeadline(t time.Time) error { return nil }
-func (c fakeNetConn) SetWriteDeadline(t time.Time) error { return nil }
-
-type fakeAddr int
-
-var (
- localAddr = fakeAddr(1)
- remoteAddr = fakeAddr(2)
-)
-
-func (a fakeAddr) Network() string {
- return "net"
-}
-
-func (a fakeAddr) String() string {
- return "str"
-}
-
-func TestFraming(t *testing.T) {
- frameSizes := []int{0, 1, 2, 124, 125, 126, 127, 128, 129, 65534, 65535, 65536, 65537}
- var readChunkers = []struct {
- name string
- f func(io.Reader) io.Reader
- }{
- {"half", iotest.HalfReader},
- {"one", iotest.OneByteReader},
- {"asis", func(r io.Reader) io.Reader { return r }},
- }
- writeBuf := make([]byte, 65537)
- for i := range writeBuf {
- writeBuf[i] = byte(i)
- }
- var writers = []struct {
- name string
- f func(w io.Writer, n int) (int, error)
- }{
- {"iocopy", func(w io.Writer, n int) (int, error) {
- nn, err := io.Copy(w, bytes.NewReader(writeBuf[:n]))
- return int(nn), err
- }},
- {"write", func(w io.Writer, n int) (int, error) {
- return w.Write(writeBuf[:n])
- }},
- {"string", func(w io.Writer, n int) (int, error) {
- return io.WriteString(w, string(writeBuf[:n]))
- }},
- }
-
- for _, compress := range []bool{false, true} {
- for _, isServer := range []bool{true, false} {
- for _, chunker := range readChunkers {
-
- var connBuf bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
- rc := newConn(fakeNetConn{Reader: chunker.f(&connBuf), Writer: nil}, !isServer, 1024, 1024)
- if compress {
- wc.newCompressionWriter = compressNoContextTakeover
- rc.newDecompressionReader = decompressNoContextTakeover
- }
- for _, n := range frameSizes {
- for _, writer := range writers {
- name := fmt.Sprintf("z:%v, s:%v, r:%s, n:%d w:%s", compress, isServer, chunker.name, n, writer.name)
-
- w, err := wc.NextWriter(TextMessage)
- if err != nil {
- t.Errorf("%s: wc.NextWriter() returned %v", name, err)
- continue
- }
- nn, err := writer.f(w, n)
- if err != nil || nn != n {
- t.Errorf("%s: w.Write(writeBuf[:n]) returned %d, %v", name, nn, err)
- continue
- }
- err = w.Close()
- if err != nil {
- t.Errorf("%s: w.Close() returned %v", name, err)
- continue
- }
-
- opCode, r, err := rc.NextReader()
- if err != nil || opCode != TextMessage {
- t.Errorf("%s: NextReader() returned %d, r, %v", name, opCode, err)
- continue
- }
- rbuf, err := ioutil.ReadAll(r)
- if err != nil {
- t.Errorf("%s: ReadFull() returned rbuf, %v", name, err)
- continue
- }
-
- if len(rbuf) != n {
- t.Errorf("%s: len(rbuf) is %d, want %d", name, len(rbuf), n)
- continue
- }
-
- for i, b := range rbuf {
- if byte(i) != b {
- t.Errorf("%s: bad byte at offset %d", name, i)
- break
- }
- }
- }
- }
- }
- }
- }
-}
-
-func TestControl(t *testing.T) {
- const message = "this is a ping/pong messsage"
- for _, isServer := range []bool{true, false} {
- for _, isWriteControl := range []bool{true, false} {
- name := fmt.Sprintf("s:%v, wc:%v", isServer, isWriteControl)
- var connBuf bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
- rc := newConn(fakeNetConn{Reader: &connBuf, Writer: nil}, !isServer, 1024, 1024)
- if isWriteControl {
- wc.WriteControl(PongMessage, []byte(message), time.Now().Add(time.Second))
- } else {
- w, err := wc.NextWriter(PongMessage)
- if err != nil {
- t.Errorf("%s: wc.NextWriter() returned %v", name, err)
- continue
- }
- if _, err := w.Write([]byte(message)); err != nil {
- t.Errorf("%s: w.Write() returned %v", name, err)
- continue
- }
- if err := w.Close(); err != nil {
- t.Errorf("%s: w.Close() returned %v", name, err)
- continue
- }
- var actualMessage string
- rc.SetPongHandler(func(s string) error { actualMessage = s; return nil })
- rc.NextReader()
- if actualMessage != message {
- t.Errorf("%s: pong=%q, want %q", name, actualMessage, message)
- continue
- }
- }
- }
- }
-}
-
-func TestCloseFrameBeforeFinalMessageFrame(t *testing.T) {
- const bufSize = 512
-
- expectedErr := &CloseError{Code: CloseNormalClosure, Text: "hello"}
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(make([]byte, bufSize+bufSize/2))
- wc.WriteControl(CloseMessage, FormatCloseMessage(expectedErr.Code, expectedErr.Text), time.Now().Add(10*time.Second))
- w.Close()
-
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("NextReader() returned %d, %v", op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if !reflect.DeepEqual(err, expectedErr) {
- t.Fatalf("io.Copy() returned %v, want %v", err, expectedErr)
- }
- _, _, err = rc.NextReader()
- if !reflect.DeepEqual(err, expectedErr) {
- t.Fatalf("NextReader() returned %v, want %v", err, expectedErr)
- }
-}
-
-func TestEOFWithinFrame(t *testing.T) {
- const bufSize = 64
-
- for n := 0; ; n++ {
- var b bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b}, false, 1024, 1024)
- rc := newConn(fakeNetConn{Reader: &b, Writer: nil}, true, 1024, 1024)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(make([]byte, bufSize))
- w.Close()
-
- if n >= b.Len() {
- break
- }
- b.Truncate(n)
-
- op, r, err := rc.NextReader()
- if err == errUnexpectedEOF {
- continue
- }
- if op != BinaryMessage || err != nil {
- t.Fatalf("%d: NextReader() returned %d, %v", n, op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if err != errUnexpectedEOF {
- t.Fatalf("%d: io.Copy() returned %v, want %v", n, err, errUnexpectedEOF)
- }
- _, _, err = rc.NextReader()
- if err != errUnexpectedEOF {
- t.Fatalf("%d: NextReader() returned %v, want %v", n, err, errUnexpectedEOF)
- }
- }
-}
-
-func TestEOFBeforeFinalFrame(t *testing.T) {
- const bufSize = 512
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(make([]byte, bufSize+bufSize/2))
-
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("NextReader() returned %d, %v", op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if err != errUnexpectedEOF {
- t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
- }
- _, _, err = rc.NextReader()
- if err != errUnexpectedEOF {
- t.Fatalf("NextReader() returned %v, want %v", err, errUnexpectedEOF)
- }
-}
-
-func TestWriteAfterMessageWriterClose(t *testing.T) {
- wc := newConn(fakeNetConn{Reader: nil, Writer: &bytes.Buffer{}}, false, 1024, 1024)
- w, _ := wc.NextWriter(BinaryMessage)
- io.WriteString(w, "hello")
- if err := w.Close(); err != nil {
- t.Fatalf("unxpected error closing message writer, %v", err)
- }
-
- if _, err := io.WriteString(w, "world"); err == nil {
- t.Fatalf("no error writing after close")
- }
-
- w, _ = wc.NextWriter(BinaryMessage)
- io.WriteString(w, "hello")
-
- // close w by getting next writer
- _, err := wc.NextWriter(BinaryMessage)
- if err != nil {
- t.Fatalf("unexpected error getting next writer, %v", err)
- }
-
- if _, err := io.WriteString(w, "world"); err == nil {
- t.Fatalf("no error writing after close")
- }
-}
-
-func TestReadLimit(t *testing.T) {
-
- const readLimit = 512
- message := make([]byte, readLimit+1)
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, readLimit-2)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
- rc.SetReadLimit(readLimit)
-
- // Send message at the limit with interleaved pong.
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(message[:readLimit-1])
- wc.WriteControl(PongMessage, []byte("this is a pong"), time.Now().Add(10*time.Second))
- w.Write(message[:1])
- w.Close()
-
- // Send message larger than the limit.
- wc.WriteMessage(BinaryMessage, message[:readLimit+1])
-
- op, _, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("1: NextReader() returned %d, %v", op, err)
- }
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("2: NextReader() returned %d, %v", op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if err != ErrReadLimit {
- t.Fatalf("io.Copy() returned %v", err)
- }
-}
-
-func TestAddrs(t *testing.T) {
- c := newConn(&fakeNetConn{}, true, 1024, 1024)
- if c.LocalAddr() != localAddr {
- t.Errorf("LocalAddr = %v, want %v", c.LocalAddr(), localAddr)
- }
- if c.RemoteAddr() != remoteAddr {
- t.Errorf("RemoteAddr = %v, want %v", c.RemoteAddr(), remoteAddr)
- }
-}
-
-func TestUnderlyingConn(t *testing.T) {
- var b1, b2 bytes.Buffer
- fc := fakeNetConn{Reader: &b1, Writer: &b2}
- c := newConn(fc, true, 1024, 1024)
- ul := c.UnderlyingConn()
- if ul != fc {
- t.Fatalf("Underlying conn is not what it should be.")
- }
-}
-
-func TestBufioReadBytes(t *testing.T) {
- // Test calling bufio.ReadBytes for value longer than read buffer size.
-
- m := make([]byte, 512)
- m[len(m)-1] = '\n'
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, len(m)+64, len(m)+64)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, len(m)-64, len(m)-64)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(m)
- w.Close()
-
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("NextReader() returned %d, %v", op, err)
- }
-
- br := bufio.NewReader(r)
- p, err := br.ReadBytes('\n')
- if err != nil {
- t.Fatalf("ReadBytes() returned %v", err)
- }
- if len(p) != len(m) {
- t.Fatalf("read returned %d bytes, want %d bytes", len(p), len(m))
- }
-}
-
-var closeErrorTests = []struct {
- err error
- codes []int
- ok bool
-}{
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNormalClosure}, true},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived}, false},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived, CloseNormalClosure}, true},
- {errors.New("hello"), []int{CloseNormalClosure}, false},
-}
-
-func TestCloseError(t *testing.T) {
- for _, tt := range closeErrorTests {
- ok := IsCloseError(tt.err, tt.codes...)
- if ok != tt.ok {
- t.Errorf("IsCloseError(%#v, %#v) returned %v, want %v", tt.err, tt.codes, ok, tt.ok)
- }
- }
-}
-
-var unexpectedCloseErrorTests = []struct {
- err error
- codes []int
- ok bool
-}{
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNormalClosure}, false},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived}, true},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived, CloseNormalClosure}, false},
- {errors.New("hello"), []int{CloseNormalClosure}, false},
-}
-
-func TestUnexpectedCloseErrors(t *testing.T) {
- for _, tt := range unexpectedCloseErrorTests {
- ok := IsUnexpectedCloseError(tt.err, tt.codes...)
- if ok != tt.ok {
- t.Errorf("IsUnexpectedCloseError(%#v, %#v) returned %v, want %v", tt.err, tt.codes, ok, tt.ok)
- }
- }
-}
-
-type blockingWriter struct {
- c1, c2 chan struct{}
-}
-
-func (w blockingWriter) Write(p []byte) (int, error) {
- // Allow main to continue
- close(w.c1)
- // Wait for panic in main
- <-w.c2
- return len(p), nil
-}
-
-func TestConcurrentWritePanic(t *testing.T) {
- w := blockingWriter{make(chan struct{}), make(chan struct{})}
- c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024)
- go func() {
- c.WriteMessage(TextMessage, []byte{})
- }()
-
- // wait for goroutine to block in write.
- <-w.c1
-
- defer func() {
- close(w.c2)
- if v := recover(); v != nil {
- return
- }
- }()
-
- c.WriteMessage(TextMessage, []byte{})
- t.Fatal("should not get here")
-}
-
-type failingReader struct{}
-
-func (r failingReader) Read(p []byte) (int, error) {
- return 0, io.EOF
-}
-
-func TestFailedConnectionReadPanic(t *testing.T) {
- c := newConn(fakeNetConn{Reader: failingReader{}, Writer: nil}, false, 1024, 1024)
-
- defer func() {
- if v := recover(); v != nil {
- return
- }
- }()
-
- for i := 0; i < 20000; i++ {
- c.ReadMessage()
- }
- t.Fatal("should not get here")
-}
-
-func TestBufioReuse(t *testing.T) {
- brw := bufio.NewReadWriter(bufio.NewReader(nil), bufio.NewWriter(nil))
- c := newConnBRW(nil, false, 0, 0, brw)
-
- if c.br != brw.Reader {
- t.Error("connection did not reuse bufio.Reader")
- }
-
- var wh writeHook
- brw.Writer.Reset(&wh)
- brw.WriteByte(0)
- brw.Flush()
- if &c.writeBuf[0] != &wh.p[0] {
- t.Error("connection did not reuse bufio.Writer")
- }
-
- brw = bufio.NewReadWriter(bufio.NewReaderSize(nil, 0), bufio.NewWriterSize(nil, 0))
- c = newConnBRW(nil, false, 0, 0, brw)
-
- if c.br == brw.Reader {
- t.Error("connection used bufio.Reader with small size")
- }
-
- brw.Writer.Reset(&wh)
- brw.WriteByte(0)
- brw.Flush()
- if &c.writeBuf[0] != &wh.p[0] {
- t.Error("connection used bufio.Writer with small size")
- }
-
-}
diff --git a/vendor/github.com/gorilla/websocket/conn_write.go b/vendor/github.com/gorilla/websocket/conn_write.go
new file mode 100644
index 000000000..a509a21f8
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/conn_write.go
@@ -0,0 +1,15 @@
+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.8
+
+package websocket
+
+import "net"
+
+func (c *Conn) writeBufs(bufs ...[]byte) error {
+ b := net.Buffers(bufs)
+ _, err := b.WriteTo(c.conn)
+ return err
+}
diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go
new file mode 100644
index 000000000..37edaff5a
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/conn_write_legacy.go
@@ -0,0 +1,18 @@
+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.8
+
+package websocket
+
+func (c *Conn) writeBufs(bufs ...[]byte) error {
+ for _, buf := range bufs {
+ if len(buf) > 0 {
+ if _, err := c.conn.Write(buf); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/gorilla/websocket/example_test.go b/vendor/github.com/gorilla/websocket/example_test.go
deleted file mode 100644
index 96449eac7..000000000
--- a/vendor/github.com/gorilla/websocket/example_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket 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 websocket_test
-
-import (
- "log"
- "net/http"
- "testing"
-
- "github.com/gorilla/websocket"
-)
-
-var (
- c *websocket.Conn
- req *http.Request
-)
-
-// The websocket.IsUnexpectedCloseError function is useful for identifying
-// application and protocol errors.
-//
-// This server application works with a client application running in the
-// browser. The client application does not explicitly close the websocket. The
-// only expected close message from the client has the code
-// websocket.CloseGoingAway. All other other close messages are likely the
-// result of an application or protocol error and are logged to aid debugging.
-func ExampleIsUnexpectedCloseError() {
-
- for {
- messageType, p, err := c.ReadMessage()
- if err != nil {
- if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
- log.Printf("error: %v, user-agent: %v", err, req.Header.Get("User-Agent"))
- }
- return
- }
- processMesage(messageType, p)
- }
-}
-
-func processMesage(mt int, p []byte) {}
-
-// TestX prevents godoc from showing this entire file in the example. Remove
-// this function when a second example is added.
-func TestX(t *testing.T) {}
diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/README.md b/vendor/github.com/gorilla/websocket/examples/autobahn/README.md
deleted file mode 100644
index 075ac1530..000000000
--- a/vendor/github.com/gorilla/websocket/examples/autobahn/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Test Server
-
-This package contains a server for the [Autobahn WebSockets Test Suite](http://autobahn.ws/testsuite).
-
-To test the server, run
-
- go run server.go
-
-and start the client test driver
-
- wstest -m fuzzingclient -s fuzzingclient.json
-
-When the client completes, it writes a report to reports/clients/index.html.
diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json b/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json
deleted file mode 100644
index aa3a0bc0a..000000000
--- a/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json
+++ /dev/null
@@ -1,15 +0,0 @@
-
-{
- "options": {"failByDrop": false},
- "outdir": "./reports/clients",
- "servers": [
- {"agent": "ReadAllWriteMessage", "url": "ws://localhost:9000/m", "options": {"version": 18}},
- {"agent": "ReadAllWritePreparedMessage", "url": "ws://localhost:9000/p", "options": {"version": 18}},
- {"agent": "ReadAllWrite", "url": "ws://localhost:9000/r", "options": {"version": 18}},
- {"agent": "CopyFull", "url": "ws://localhost:9000/f", "options": {"version": 18}},
- {"agent": "CopyWriterOnly", "url": "ws://localhost:9000/c", "options": {"version": 18}}
- ],
- "cases": ["*"],
- "exclude-cases": [],
- "exclude-agent-cases": {}
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/server.go b/vendor/github.com/gorilla/websocket/examples/autobahn/server.go
deleted file mode 100644
index 3db880f90..000000000
--- a/vendor/github.com/gorilla/websocket/examples/autobahn/server.go
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Command server is a test server for the Autobahn WebSockets Test Suite.
-package main
-
-import (
- "errors"
- "flag"
- "io"
- "log"
- "net/http"
- "time"
- "unicode/utf8"
-
- "github.com/gorilla/websocket"
-)
-
-var upgrader = websocket.Upgrader{
- ReadBufferSize: 4096,
- WriteBufferSize: 4096,
- EnableCompression: true,
- CheckOrigin: func(r *http.Request) bool {
- return true
- },
-}
-
-// echoCopy echoes messages from the client using io.Copy.
-func echoCopy(w http.ResponseWriter, r *http.Request, writerOnly bool) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("Upgrade:", err)
- return
- }
- defer conn.Close()
- for {
- mt, r, err := conn.NextReader()
- if err != nil {
- if err != io.EOF {
- log.Println("NextReader:", err)
- }
- return
- }
- if mt == websocket.TextMessage {
- r = &validator{r: r}
- }
- w, err := conn.NextWriter(mt)
- if err != nil {
- log.Println("NextWriter:", err)
- return
- }
- if mt == websocket.TextMessage {
- r = &validator{r: r}
- }
- if writerOnly {
- _, err = io.Copy(struct{ io.Writer }{w}, r)
- } else {
- _, err = io.Copy(w, r)
- }
- if err != nil {
- if err == errInvalidUTF8 {
- conn.WriteControl(websocket.CloseMessage,
- websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
- time.Time{})
- }
- log.Println("Copy:", err)
- return
- }
- err = w.Close()
- if err != nil {
- log.Println("Close:", err)
- return
- }
- }
-}
-
-func echoCopyWriterOnly(w http.ResponseWriter, r *http.Request) {
- echoCopy(w, r, true)
-}
-
-func echoCopyFull(w http.ResponseWriter, r *http.Request) {
- echoCopy(w, r, false)
-}
-
-// echoReadAll echoes messages from the client by reading the entire message
-// with ioutil.ReadAll.
-func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrepared bool) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("Upgrade:", err)
- return
- }
- defer conn.Close()
- for {
- mt, b, err := conn.ReadMessage()
- if err != nil {
- if err != io.EOF {
- log.Println("NextReader:", err)
- }
- return
- }
- if mt == websocket.TextMessage {
- if !utf8.Valid(b) {
- conn.WriteControl(websocket.CloseMessage,
- websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
- time.Time{})
- log.Println("ReadAll: invalid utf8")
- }
- }
- if writeMessage {
- if !writePrepared {
- err = conn.WriteMessage(mt, b)
- if err != nil {
- log.Println("WriteMessage:", err)
- }
- } else {
- pm, err := websocket.NewPreparedMessage(mt, b)
- if err != nil {
- log.Println("NewPreparedMessage:", err)
- return
- }
- err = conn.WritePreparedMessage(pm)
- if err != nil {
- log.Println("WritePreparedMessage:", err)
- }
- }
- } else {
- w, err := conn.NextWriter(mt)
- if err != nil {
- log.Println("NextWriter:", err)
- return
- }
- if _, err := w.Write(b); err != nil {
- log.Println("Writer:", err)
- return
- }
- if err := w.Close(); err != nil {
- log.Println("Close:", err)
- return
- }
- }
- }
-}
-
-func echoReadAllWriter(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, false, false)
-}
-
-func echoReadAllWriteMessage(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, true, false)
-}
-
-func echoReadAllWritePreparedMessage(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, true, true)
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found.", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- io.WriteString(w, "<html><body>Echo Server</body></html>")
-}
-
-var addr = flag.String("addr", ":9000", "http service address")
-
-func main() {
- flag.Parse()
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/c", echoCopyWriterOnly)
- http.HandleFunc("/f", echoCopyFull)
- http.HandleFunc("/r", echoReadAllWriter)
- http.HandleFunc("/m", echoReadAllWriteMessage)
- http.HandleFunc("/p", echoReadAllWritePreparedMessage)
- err := http.ListenAndServe(*addr, nil)
- if err != nil {
- log.Fatal("ListenAndServe: ", err)
- }
-}
-
-type validator struct {
- state int
- x rune
- r io.Reader
-}
-
-var errInvalidUTF8 = errors.New("invalid utf8")
-
-func (r *validator) Read(p []byte) (int, error) {
- n, err := r.r.Read(p)
- state := r.state
- x := r.x
- for _, b := range p[:n] {
- state, x = decode(state, x, b)
- if state == utf8Reject {
- break
- }
- }
- r.state = state
- r.x = x
- if state == utf8Reject || (err == io.EOF && state != utf8Accept) {
- return n, errInvalidUTF8
- }
- return n, err
-}
-
-// UTF-8 decoder from http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
-//
-// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-//
-// 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.
-var utf8d = [...]byte{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7f
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9f
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // a0..bf
- 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c0..df
- 0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // e0..ef
- 0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // f0..ff
- 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
- 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
- 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
- 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // s7..s8
-}
-
-const (
- utf8Accept = 0
- utf8Reject = 1
-)
-
-func decode(state int, x rune, b byte) (int, rune) {
- t := utf8d[b]
- if state != utf8Accept {
- x = rune(b&0x3f) | (x << 6)
- } else {
- x = rune((0xff >> t) & b)
- }
- state = int(utf8d[256+state*16+int(t)])
- return state, x
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/README.md b/vendor/github.com/gorilla/websocket/examples/chat/README.md
deleted file mode 100644
index 7baf3e328..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/README.md
+++ /dev/null
@@ -1,102 +0,0 @@
-# Chat Example
-
-This application shows how to use the
-[websocket](https://github.com/gorilla/websocket) package to implement a simple
-web chat application.
-
-## Running the example
-
-The example requires a working Go development environment. The [Getting
-Started](http://golang.org/doc/install) page describes how to install the
-development environment.
-
-Once you have Go up and running, you can download, build and run the example
-using the following commands.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/chat`
- $ go run *.go
-
-To use the chat example, open http://localhost:8080/ in your browser.
-
-## Server
-
-The server application defines two types, `Client` and `Hub`. The server
-creates an instance of the `Client` type for each websocket connection. A
-`Client` acts as an intermediary between the websocket connection and a single
-instance of the `Hub` type. The `Hub` maintains a set of registered clients and
-broadcasts messages to the clients.
-
-The application runs one goroutine for the `Hub` and two goroutines for each
-`Client`. The goroutines communicate with each other using channels. The `Hub`
-has channels for registering clients, unregistering clients and broadcasting
-messages. A `Client` has a buffered channel of outbound messages. One of the
-client's goroutines reads messages from this channel and writes the messages to
-the websocket. The other client goroutine reads messages from the websocket and
-sends them to the hub.
-
-### Hub
-
-The code for the `Hub` type is in
-[hub.go](https://github.com/gorilla/websocket/blob/master/examples/chat/hub.go).
-The application's `main` function starts the hub's `run` method as a goroutine.
-Clients send requests to the hub using the `register`, `unregister` and
-`broadcast` channels.
-
-The hub registers clients by adding the client pointer as a key in the
-`clients` map. The map value is always true.
-
-The unregister code is a little more complicated. In addition to deleting the
-client pointer from the `clients` map, the hub closes the clients's `send`
-channel to signal the client that no more messages will be sent to the client.
-
-The hub handles messages by looping over the registered clients and sending the
-message to the client's `send` channel. If the client's `send` buffer is full,
-then the hub assumes that the client is dead or stuck. In this case, the hub
-unregisters the client and closes the websocket.
-
-### Client
-
-The code for the `Client` type is in [client.go](https://github.com/gorilla/websocket/blob/master/examples/chat/client.go).
-
-The `serveWs` function is registered by the application's `main` function as
-an HTTP handler. The handler upgrades the HTTP connection to the WebSocket
-protocol, creates a client, registers the client with the hub and schedules the
-client to be unregistered using a defer statement.
-
-Next, the HTTP handler starts the client's `writePump` method as a goroutine.
-This method transfers messages from the client's send channel to the websocket
-connection. The writer method exits when the channel is closed by the hub or
-there's an error writing to the websocket connection.
-
-Finally, the HTTP handler calls the client's `readPump` method. This method
-transfers inbound messages from the websocket to the hub.
-
-WebSocket connections [support one concurrent reader and one concurrent
-writer](https://godoc.org/github.com/gorilla/websocket#hdr-Concurrency). The
-application ensures that these concurrency requirements are met by executing
-all reads from the `readPump` goroutine and all writes from the `writePump`
-goroutine.
-
-To improve efficiency under high load, the `writePump` function coalesces
-pending chat messages in the `send` channel to a single WebSocket message. This
-reduces the number of system calls and the amount of data sent over the
-network.
-
-## Frontend
-
-The frontend code is in [home.html](https://github.com/gorilla/websocket/blob/master/examples/chat/home.html).
-
-On document load, the script checks for websocket functionality in the browser.
-If websocket functionality is available, then the script opens a connection to
-the server and registers a callback to handle messages from the server. The
-callback appends the message to the chat log using the appendLog function.
-
-To allow the user to manually scroll through the chat log without interruption
-from new messages, the `appendLog` function checks the scroll position before
-adding new content. If the chat log is scrolled to the bottom, then the
-function scrolls new content into view after adding the content. Otherwise, the
-scroll position is not changed.
-
-The form handler writes the user input to the websocket and clears the input
-field.
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/client.go b/vendor/github.com/gorilla/websocket/examples/chat/client.go
deleted file mode 100644
index 9461c1ea0..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/client.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 main
-
-import (
- "bytes"
- "log"
- "net/http"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-const (
- // Time allowed to write a message to the peer.
- writeWait = 10 * time.Second
-
- // Time allowed to read the next pong message from the peer.
- pongWait = 60 * time.Second
-
- // Send pings to peer with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Maximum message size allowed from peer.
- maxMessageSize = 512
-)
-
-var (
- newline = []byte{'\n'}
- space = []byte{' '}
-)
-
-var upgrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
-}
-
-// Client is a middleman between the websocket connection and the hub.
-type Client struct {
- hub *Hub
-
- // The websocket connection.
- conn *websocket.Conn
-
- // Buffered channel of outbound messages.
- send chan []byte
-}
-
-// readPump pumps messages from the websocket connection to the hub.
-//
-// The application runs readPump in a per-connection goroutine. The application
-// ensures that there is at most one reader on a connection by executing all
-// reads from this goroutine.
-func (c *Client) readPump() {
- defer func() {
- c.hub.unregister <- c
- c.conn.Close()
- }()
- c.conn.SetReadLimit(maxMessageSize)
- c.conn.SetReadDeadline(time.Now().Add(pongWait))
- c.conn.SetPongHandler(func(string) error { c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, message, err := c.conn.ReadMessage()
- if err != nil {
- if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
- log.Printf("error: %v", err)
- }
- break
- }
- message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))
- c.hub.broadcast <- message
- }
-}
-
-// writePump pumps messages from the hub to the websocket connection.
-//
-// A goroutine running writePump is started for each connection. The
-// application ensures that there is at most one writer to a connection by
-// executing all writes from this goroutine.
-func (c *Client) writePump() {
- ticker := time.NewTicker(pingPeriod)
- defer func() {
- ticker.Stop()
- c.conn.Close()
- }()
- for {
- select {
- case message, ok := <-c.send:
- c.conn.SetWriteDeadline(time.Now().Add(writeWait))
- if !ok {
- // The hub closed the channel.
- c.conn.WriteMessage(websocket.CloseMessage, []byte{})
- return
- }
-
- w, err := c.conn.NextWriter(websocket.TextMessage)
- if err != nil {
- return
- }
- w.Write(message)
-
- // Add queued chat messages to the current websocket message.
- n := len(c.send)
- for i := 0; i < n; i++ {
- w.Write(newline)
- w.Write(<-c.send)
- }
-
- if err := w.Close(); err != nil {
- return
- }
- case <-ticker.C:
- c.conn.SetWriteDeadline(time.Now().Add(writeWait))
- if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
- return
- }
- }
- }
-}
-
-// serveWs handles websocket requests from the peer.
-func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println(err)
- return
- }
- client := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)}
- client.hub.register <- client
-
- // Allow collection of memory referenced by the caller by doing all work in
- // new goroutines.
- go client.writePump()
- go client.readPump()
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/home.html b/vendor/github.com/gorilla/websocket/examples/chat/home.html
deleted file mode 100644
index a39a0c276..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/home.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Chat Example</title>
-<script type="text/javascript">
-window.onload = function () {
- var conn;
- var msg = document.getElementById("msg");
- var log = document.getElementById("log");
-
- function appendLog(item) {
- var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
- log.appendChild(item);
- if (doScroll) {
- log.scrollTop = log.scrollHeight - log.clientHeight;
- }
- }
-
- document.getElementById("form").onsubmit = function () {
- if (!conn) {
- return false;
- }
- if (!msg.value) {
- return false;
- }
- conn.send(msg.value);
- msg.value = "";
- return false;
- };
-
- if (window["WebSocket"]) {
- conn = new WebSocket("ws://" + document.location.host + "/ws");
- conn.onclose = function (evt) {
- var item = document.createElement("div");
- item.innerHTML = "<b>Connection closed.</b>";
- appendLog(item);
- };
- conn.onmessage = function (evt) {
- var messages = evt.data.split('\n');
- for (var i = 0; i < messages.length; i++) {
- var item = document.createElement("div");
- item.innerText = messages[i];
- appendLog(item);
- }
- };
- } else {
- var item = document.createElement("div");
- item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
- appendLog(item);
- }
-};
-</script>
-<style type="text/css">
-html {
- overflow: hidden;
-}
-
-body {
- overflow: hidden;
- padding: 0;
- margin: 0;
- width: 100%;
- height: 100%;
- background: gray;
-}
-
-#log {
- background: white;
- margin: 0;
- padding: 0.5em 0.5em 0.5em 0.5em;
- position: absolute;
- top: 0.5em;
- left: 0.5em;
- right: 0.5em;
- bottom: 3em;
- overflow: auto;
-}
-
-#form {
- padding: 0 0.5em 0 0.5em;
- margin: 0;
- position: absolute;
- bottom: 1em;
- left: 0px;
- width: 100%;
- overflow: hidden;
-}
-
-</style>
-</head>
-<body>
-<div id="log"></div>
-<form id="form">
- <input type="submit" value="Send" />
- <input type="text" id="msg" size="64"/>
-</form>
-</body>
-</html>
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/hub.go b/vendor/github.com/gorilla/websocket/examples/chat/hub.go
deleted file mode 100644
index 7f07ea079..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/hub.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 main
-
-// hub maintains the set of active clients and broadcasts messages to the
-// clients.
-type Hub struct {
- // Registered clients.
- clients map[*Client]bool
-
- // Inbound messages from the clients.
- broadcast chan []byte
-
- // Register requests from the clients.
- register chan *Client
-
- // Unregister requests from clients.
- unregister chan *Client
-}
-
-func newHub() *Hub {
- return &Hub{
- broadcast: make(chan []byte),
- register: make(chan *Client),
- unregister: make(chan *Client),
- clients: make(map[*Client]bool),
- }
-}
-
-func (h *Hub) run() {
- for {
- select {
- case client := <-h.register:
- h.clients[client] = true
- case client := <-h.unregister:
- if _, ok := h.clients[client]; ok {
- delete(h.clients, client)
- close(client.send)
- }
- case message := <-h.broadcast:
- for client := range h.clients {
- select {
- case client.send <- message:
- default:
- close(client.send)
- delete(h.clients, client)
- }
- }
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/main.go b/vendor/github.com/gorilla/websocket/examples/chat/main.go
deleted file mode 100644
index 74615d59c..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/main.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 main
-
-import (
- "flag"
- "log"
- "net/http"
-)
-
-var addr = flag.String("addr", ":8080", "http service address")
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- log.Println(r.URL)
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- http.ServeFile(w, r, "home.html")
-}
-
-func main() {
- flag.Parse()
- hub := newHub()
- go hub.run()
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
- serveWs(hub, w, r)
- })
- err := http.ListenAndServe(*addr, nil)
- if err != nil {
- log.Fatal("ListenAndServe: ", err)
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/command/README.md b/vendor/github.com/gorilla/websocket/examples/command/README.md
deleted file mode 100644
index ed6f78684..000000000
--- a/vendor/github.com/gorilla/websocket/examples/command/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Command example
-
-This example connects a websocket connection to stdin and stdout of a command.
-Received messages are written to stdin followed by a `\n`. Each line read from
-standard out is sent as a message to the client.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/command`
- $ go run main.go <command and arguments to run>
- # Open http://localhost:8080/ .
-
-Try the following commands.
-
- # Echo sent messages to the output area.
- $ go run main.go cat
-
- # Run a shell.Try sending "ls" and "cat main.go".
- $ go run main.go sh
-
diff --git a/vendor/github.com/gorilla/websocket/examples/command/home.html b/vendor/github.com/gorilla/websocket/examples/command/home.html
deleted file mode 100644
index 19c46128a..000000000
--- a/vendor/github.com/gorilla/websocket/examples/command/home.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Command Example</title>
-<script type="text/javascript">
-window.onload = function () {
- var conn;
- var msg = document.getElementById("msg");
- var log = document.getElementById("log");
-
- function appendLog(item) {
- var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
- log.appendChild(item);
- if (doScroll) {
- log.scrollTop = log.scrollHeight - log.clientHeight;
- }
- }
-
- document.getElementById("form").onsubmit = function () {
- if (!conn) {
- return false;
- }
- if (!msg.value) {
- return false;
- }
- conn.send(msg.value);
- msg.value = "";
- return false;
- };
-
- if (window["WebSocket"]) {
- conn = new WebSocket("ws://" + document.location.host + "/ws");
- conn.onclose = function (evt) {
- var item = document.createElement("div");
- item.innerHTML = "<b>Connection closed.</b>";
- appendLog(item);
- };
- conn.onmessage = function (evt) {
- var messages = evt.data.split('\n');
- for (var i = 0; i < messages.length; i++) {
- var item = document.createElement("div");
- item.innerText = messages[i];
- appendLog(item);
- }
- };
- } else {
- var item = document.createElement("div");
- item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
- appendLog(item);
- }
-};
-</script>
-<style type="text/css">
-html {
- overflow: hidden;
-}
-
-body {
- overflow: hidden;
- padding: 0;
- margin: 0;
- width: 100%;
- height: 100%;
- background: gray;
-}
-
-#log {
- background: white;
- margin: 0;
- padding: 0.5em 0.5em 0.5em 0.5em;
- position: absolute;
- top: 0.5em;
- left: 0.5em;
- right: 0.5em;
- bottom: 3em;
- overflow: auto;
-}
-
-#log pre {
- margin: 0;
-}
-
-#form {
- padding: 0 0.5em 0 0.5em;
- margin: 0;
- position: absolute;
- bottom: 1em;
- left: 0px;
- width: 100%;
- overflow: hidden;
-}
-
-</style>
-</head>
-<body>
-<div id="log"></div>
-<form id="form">
- <input type="submit" value="Send" />
- <input type="text" id="msg" size="64"/>
-</form>
-</body>
-</html>
diff --git a/vendor/github.com/gorilla/websocket/examples/command/main.go b/vendor/github.com/gorilla/websocket/examples/command/main.go
deleted file mode 100644
index 239c5c85c..000000000
--- a/vendor/github.com/gorilla/websocket/examples/command/main.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket 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 main
-
-import (
- "bufio"
- "flag"
- "io"
- "log"
- "net/http"
- "os"
- "os/exec"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-var (
- addr = flag.String("addr", "127.0.0.1:8080", "http service address")
- cmdPath string
-)
-
-const (
- // Time allowed to write a message to the peer.
- writeWait = 10 * time.Second
-
- // Maximum message size allowed from peer.
- maxMessageSize = 8192
-
- // Time allowed to read the next pong message from the peer.
- pongWait = 60 * time.Second
-
- // Send pings to peer with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Time to wait before force close on connection.
- closeGracePeriod = 10 * time.Second
-)
-
-func pumpStdin(ws *websocket.Conn, w io.Writer) {
- defer ws.Close()
- ws.SetReadLimit(maxMessageSize)
- ws.SetReadDeadline(time.Now().Add(pongWait))
- ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, message, err := ws.ReadMessage()
- if err != nil {
- break
- }
- message = append(message, '\n')
- if _, err := w.Write(message); err != nil {
- break
- }
- }
-}
-
-func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
- defer func() {
- }()
- s := bufio.NewScanner(r)
- for s.Scan() {
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil {
- ws.Close()
- break
- }
- }
- if s.Err() != nil {
- log.Println("scan:", s.Err())
- }
- close(done)
-
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
- time.Sleep(closeGracePeriod)
- ws.Close()
-}
-
-func ping(ws *websocket.Conn, done chan struct{}) {
- ticker := time.NewTicker(pingPeriod)
- defer ticker.Stop()
- for {
- select {
- case <-ticker.C:
- if err := ws.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(writeWait)); err != nil {
- log.Println("ping:", err)
- }
- case <-done:
- return
- }
- }
-}
-
-func internalError(ws *websocket.Conn, msg string, err error) {
- log.Println(msg, err)
- ws.WriteMessage(websocket.TextMessage, []byte("Internal server error."))
-}
-
-var upgrader = websocket.Upgrader{}
-
-func serveWs(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("upgrade:", err)
- return
- }
-
- defer ws.Close()
-
- outr, outw, err := os.Pipe()
- if err != nil {
- internalError(ws, "stdout:", err)
- return
- }
- defer outr.Close()
- defer outw.Close()
-
- inr, inw, err := os.Pipe()
- if err != nil {
- internalError(ws, "stdin:", err)
- return
- }
- defer inr.Close()
- defer inw.Close()
-
- proc, err := os.StartProcess(cmdPath, flag.Args(), &os.ProcAttr{
- Files: []*os.File{inr, outw, outw},
- })
- if err != nil {
- internalError(ws, "start:", err)
- return
- }
-
- inr.Close()
- outw.Close()
-
- stdoutDone := make(chan struct{})
- go pumpStdout(ws, outr, stdoutDone)
- go ping(ws, stdoutDone)
-
- pumpStdin(ws, inw)
-
- // Some commands will exit when stdin is closed.
- inw.Close()
-
- // Other commands need a bonk on the head.
- if err := proc.Signal(os.Interrupt); err != nil {
- log.Println("inter:", err)
- }
-
- select {
- case <-stdoutDone:
- case <-time.After(time.Second):
- // A bigger bonk on the head.
- if err := proc.Signal(os.Kill); err != nil {
- log.Println("term:", err)
- }
- <-stdoutDone
- }
-
- if _, err := proc.Wait(); err != nil {
- log.Println("wait:", err)
- }
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- http.ServeFile(w, r, "home.html")
-}
-
-func main() {
- flag.Parse()
- if len(flag.Args()) < 1 {
- log.Fatal("must specify at least one argument")
- }
- var err error
- cmdPath, err = exec.LookPath(flag.Args()[0])
- if err != nil {
- log.Fatal(err)
- }
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", serveWs)
- log.Fatal(http.ListenAndServe(*addr, nil))
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/echo/README.md b/vendor/github.com/gorilla/websocket/examples/echo/README.md
deleted file mode 100644
index 6ad79ed76..000000000
--- a/vendor/github.com/gorilla/websocket/examples/echo/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Client and server example
-
-This example shows a simple client and server.
-
-The server echoes messages sent to it. The client sends a message every second
-and prints all messages received.
-
-To run the example, start the server:
-
- $ go run server.go
-
-Next, start the client:
-
- $ go run client.go
-
-The server includes a simple web client. To use the client, open
-http://127.0.0.1:8080 in the browser and follow the instructions on the page.
diff --git a/vendor/github.com/gorilla/websocket/examples/echo/client.go b/vendor/github.com/gorilla/websocket/examples/echo/client.go
deleted file mode 100644
index 6578094e7..000000000
--- a/vendor/github.com/gorilla/websocket/examples/echo/client.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "log"
- "net/url"
- "os"
- "os/signal"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-var addr = flag.String("addr", "localhost:8080", "http service address")
-
-func main() {
- flag.Parse()
- log.SetFlags(0)
-
- interrupt := make(chan os.Signal, 1)
- signal.Notify(interrupt, os.Interrupt)
-
- u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}
- log.Printf("connecting to %s", u.String())
-
- c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
- if err != nil {
- log.Fatal("dial:", err)
- }
- defer c.Close()
-
- done := make(chan struct{})
-
- go func() {
- defer c.Close()
- defer close(done)
- for {
- _, message, err := c.ReadMessage()
- if err != nil {
- log.Println("read:", err)
- return
- }
- log.Printf("recv: %s", message)
- }
- }()
-
- ticker := time.NewTicker(time.Second)
- defer ticker.Stop()
-
- for {
- select {
- case t := <-ticker.C:
- err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
- if err != nil {
- log.Println("write:", err)
- return
- }
- case <-interrupt:
- log.Println("interrupt")
- // To cleanly close a connection, a client should send a close
- // frame and wait for the server to close the connection.
- err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
- if err != nil {
- log.Println("write close:", err)
- return
- }
- select {
- case <-done:
- case <-time.After(time.Second):
- }
- c.Close()
- return
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/echo/server.go b/vendor/github.com/gorilla/websocket/examples/echo/server.go
deleted file mode 100644
index ecc680c8b..000000000
--- a/vendor/github.com/gorilla/websocket/examples/echo/server.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "html/template"
- "log"
- "net/http"
-
- "github.com/gorilla/websocket"
-)
-
-var addr = flag.String("addr", "localhost:8080", "http service address")
-
-var upgrader = websocket.Upgrader{} // use default options
-
-func echo(w http.ResponseWriter, r *http.Request) {
- c, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Print("upgrade:", err)
- return
- }
- defer c.Close()
- for {
- mt, message, err := c.ReadMessage()
- if err != nil {
- log.Println("read:", err)
- break
- }
- log.Printf("recv: %s", message)
- err = c.WriteMessage(mt, message)
- if err != nil {
- log.Println("write:", err)
- break
- }
- }
-}
-
-func home(w http.ResponseWriter, r *http.Request) {
- homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
-}
-
-func main() {
- flag.Parse()
- log.SetFlags(0)
- http.HandleFunc("/echo", echo)
- http.HandleFunc("/", home)
- log.Fatal(http.ListenAndServe(*addr, nil))
-}
-
-var homeTemplate = template.Must(template.New("").Parse(`
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<script>
-window.addEventListener("load", function(evt) {
-
- var output = document.getElementById("output");
- var input = document.getElementById("input");
- var ws;
-
- var print = function(message) {
- var d = document.createElement("div");
- d.innerHTML = message;
- output.appendChild(d);
- };
-
- document.getElementById("open").onclick = function(evt) {
- if (ws) {
- return false;
- }
- ws = new WebSocket("{{.}}");
- ws.onopen = function(evt) {
- print("OPEN");
- }
- ws.onclose = function(evt) {
- print("CLOSE");
- ws = null;
- }
- ws.onmessage = function(evt) {
- print("RESPONSE: " + evt.data);
- }
- ws.onerror = function(evt) {
- print("ERROR: " + evt.data);
- }
- return false;
- };
-
- document.getElementById("send").onclick = function(evt) {
- if (!ws) {
- return false;
- }
- print("SEND: " + input.value);
- ws.send(input.value);
- return false;
- };
-
- document.getElementById("close").onclick = function(evt) {
- if (!ws) {
- return false;
- }
- ws.close();
- return false;
- };
-
-});
-</script>
-</head>
-<body>
-<table>
-<tr><td valign="top" width="50%">
-<p>Click "Open" to create a connection to the server,
-"Send" to send a message to the server and "Close" to close the connection.
-You can change the message and send multiple times.
-<p>
-<form>
-<button id="open">Open</button>
-<button id="close">Close</button>
-<p><input id="input" type="text" value="Hello world!">
-<button id="send">Send</button>
-</form>
-</td><td valign="top" width="50%">
-<div id="output"></div>
-</td></tr></table>
-</body>
-</html>
-`))
diff --git a/vendor/github.com/gorilla/websocket/examples/filewatch/README.md b/vendor/github.com/gorilla/websocket/examples/filewatch/README.md
deleted file mode 100644
index ca4931f3b..000000000
--- a/vendor/github.com/gorilla/websocket/examples/filewatch/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# File Watch example.
-
-This example sends a file to the browser client for display whenever the file is modified.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/filewatch`
- $ go run main.go <name of file to watch>
- # Open http://localhost:8080/ .
- # Modify the file to see it update in the browser.
diff --git a/vendor/github.com/gorilla/websocket/examples/filewatch/main.go b/vendor/github.com/gorilla/websocket/examples/filewatch/main.go
deleted file mode 100644
index f5f9da5c3..000000000
--- a/vendor/github.com/gorilla/websocket/examples/filewatch/main.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 main
-
-import (
- "flag"
- "html/template"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "strconv"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-const (
- // Time allowed to write the file to the client.
- writeWait = 10 * time.Second
-
- // Time allowed to read the next pong message from the client.
- pongWait = 60 * time.Second
-
- // Send pings to client with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Poll file for changes with this period.
- filePeriod = 10 * time.Second
-)
-
-var (
- addr = flag.String("addr", ":8080", "http service address")
- homeTempl = template.Must(template.New("").Parse(homeHTML))
- filename string
- upgrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- }
-)
-
-func readFileIfModified(lastMod time.Time) ([]byte, time.Time, error) {
- fi, err := os.Stat(filename)
- if err != nil {
- return nil, lastMod, err
- }
- if !fi.ModTime().After(lastMod) {
- return nil, lastMod, nil
- }
- p, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, fi.ModTime(), err
- }
- return p, fi.ModTime(), nil
-}
-
-func reader(ws *websocket.Conn) {
- defer ws.Close()
- ws.SetReadLimit(512)
- ws.SetReadDeadline(time.Now().Add(pongWait))
- ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, _, err := ws.ReadMessage()
- if err != nil {
- break
- }
- }
-}
-
-func writer(ws *websocket.Conn, lastMod time.Time) {
- lastError := ""
- pingTicker := time.NewTicker(pingPeriod)
- fileTicker := time.NewTicker(filePeriod)
- defer func() {
- pingTicker.Stop()
- fileTicker.Stop()
- ws.Close()
- }()
- for {
- select {
- case <-fileTicker.C:
- var p []byte
- var err error
-
- p, lastMod, err = readFileIfModified(lastMod)
-
- if err != nil {
- if s := err.Error(); s != lastError {
- lastError = s
- p = []byte(lastError)
- }
- } else {
- lastError = ""
- }
-
- if p != nil {
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.TextMessage, p); err != nil {
- return
- }
- }
- case <-pingTicker.C:
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
- return
- }
- }
- }
-}
-
-func serveWs(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- if _, ok := err.(websocket.HandshakeError); !ok {
- log.Println(err)
- }
- return
- }
-
- var lastMod time.Time
- if n, err := strconv.ParseInt(r.FormValue("lastMod"), 16, 64); err == nil {
- lastMod = time.Unix(0, n)
- }
-
- go writer(ws, lastMod)
- reader(ws)
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- p, lastMod, err := readFileIfModified(time.Time{})
- if err != nil {
- p = []byte(err.Error())
- lastMod = time.Unix(0, 0)
- }
- var v = struct {
- Host string
- Data string
- LastMod string
- }{
- r.Host,
- string(p),
- strconv.FormatInt(lastMod.UnixNano(), 16),
- }
- homeTempl.Execute(w, &v)
-}
-
-func main() {
- flag.Parse()
- if flag.NArg() != 1 {
- log.Fatal("filename not specified")
- }
- filename = flag.Args()[0]
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", serveWs)
- if err := http.ListenAndServe(*addr, nil); err != nil {
- log.Fatal(err)
- }
-}
-
-const homeHTML = `<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>WebSocket Example</title>
- </head>
- <body>
- <pre id="fileData">{{.Data}}</pre>
- <script type="text/javascript">
- (function() {
- var data = document.getElementById("fileData");
- var conn = new WebSocket("ws://{{.Host}}/ws?lastMod={{.LastMod}}");
- conn.onclose = function(evt) {
- data.textContent = 'Connection closed';
- }
- conn.onmessage = function(evt) {
- console.log('file updated');
- data.textContent = evt.data;
- }
- })();
- </script>
- </body>
-</html>
-`
diff --git a/vendor/github.com/gorilla/websocket/json_test.go b/vendor/github.com/gorilla/websocket/json_test.go
deleted file mode 100644
index 61100e481..000000000
--- a/vendor/github.com/gorilla/websocket/json_test.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 websocket
-
-import (
- "bytes"
- "encoding/json"
- "io"
- "reflect"
- "testing"
-)
-
-func TestJSON(t *testing.T) {
- var buf bytes.Buffer
- c := fakeNetConn{&buf, &buf}
- wc := newConn(c, true, 1024, 1024)
- rc := newConn(c, false, 1024, 1024)
-
- var actual, expect struct {
- A int
- B string
- }
- expect.A = 1
- expect.B = "hello"
-
- if err := wc.WriteJSON(&expect); err != nil {
- t.Fatal("write", err)
- }
-
- if err := rc.ReadJSON(&actual); err != nil {
- t.Fatal("read", err)
- }
-
- if !reflect.DeepEqual(&actual, &expect) {
- t.Fatal("equal", actual, expect)
- }
-}
-
-func TestPartialJSONRead(t *testing.T) {
- var buf bytes.Buffer
- c := fakeNetConn{&buf, &buf}
- wc := newConn(c, true, 1024, 1024)
- rc := newConn(c, false, 1024, 1024)
-
- var v struct {
- A int
- B string
- }
- v.A = 1
- v.B = "hello"
-
- messageCount := 0
-
- // Partial JSON values.
-
- data, err := json.Marshal(v)
- if err != nil {
- t.Fatal(err)
- }
- for i := len(data) - 1; i >= 0; i-- {
- if err := wc.WriteMessage(TextMessage, data[:i]); err != nil {
- t.Fatal(err)
- }
- messageCount++
- }
-
- // Whitespace.
-
- if err := wc.WriteMessage(TextMessage, []byte(" ")); err != nil {
- t.Fatal(err)
- }
- messageCount++
-
- // Close.
-
- if err := wc.WriteMessage(CloseMessage, FormatCloseMessage(CloseNormalClosure, "")); err != nil {
- t.Fatal(err)
- }
-
- for i := 0; i < messageCount; i++ {
- err := rc.ReadJSON(&v)
- if err != io.ErrUnexpectedEOF {
- t.Error("read", i, err)
- }
- }
-
- err = rc.ReadJSON(&v)
- if _, ok := err.(*CloseError); !ok {
- t.Error("final", err)
- }
-}
-
-func TestDeprecatedJSON(t *testing.T) {
- var buf bytes.Buffer
- c := fakeNetConn{&buf, &buf}
- wc := newConn(c, true, 1024, 1024)
- rc := newConn(c, false, 1024, 1024)
-
- var actual, expect struct {
- A int
- B string
- }
- expect.A = 1
- expect.B = "hello"
-
- if err := WriteJSON(wc, &expect); err != nil {
- t.Fatal("write", err)
- }
-
- if err := ReadJSON(rc, &actual); err != nil {
- t.Fatal("read", err)
- }
-
- if !reflect.DeepEqual(&actual, &expect) {
- t.Fatal("equal", actual, expect)
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/mask_test.go b/vendor/github.com/gorilla/websocket/mask_test.go
deleted file mode 100644
index 298a1e509..000000000
--- a/vendor/github.com/gorilla/websocket/mask_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
-// this source code is governed by a BSD-style license that can be found in the
-// LICENSE file.
-
-// Require 1.7 for sub-bencmarks
-// +build go1.7,!appengine
-
-package websocket
-
-import (
- "fmt"
- "testing"
-)
-
-func maskBytesByByte(key [4]byte, pos int, b []byte) int {
- for i := range b {
- b[i] ^= key[pos&3]
- pos++
- }
- return pos & 3
-}
-
-func notzero(b []byte) int {
- for i := range b {
- if b[i] != 0 {
- return i
- }
- }
- return -1
-}
-
-func TestMaskBytes(t *testing.T) {
- key := [4]byte{1, 2, 3, 4}
- for size := 1; size <= 1024; size++ {
- for align := 0; align < wordSize; align++ {
- for pos := 0; pos < 4; pos++ {
- b := make([]byte, size+align)[align:]
- maskBytes(key, pos, b)
- maskBytesByByte(key, pos, b)
- if i := notzero(b); i >= 0 {
- t.Errorf("size:%d, align:%d, pos:%d, offset:%d", size, align, pos, i)
- }
- }
- }
- }
-}
-
-func BenchmarkMaskBytes(b *testing.B) {
- for _, size := range []int{2, 4, 8, 16, 32, 512, 1024} {
- b.Run(fmt.Sprintf("size-%d", size), func(b *testing.B) {
- for _, align := range []int{wordSize / 2} {
- b.Run(fmt.Sprintf("align-%d", align), func(b *testing.B) {
- for _, fn := range []struct {
- name string
- fn func(key [4]byte, pos int, b []byte) int
- }{
- {"byte", maskBytesByByte},
- {"word", maskBytes},
- } {
- b.Run(fn.name, func(b *testing.B) {
- key := newMaskKey()
- data := make([]byte, size+align)[align:]
- for i := 0; i < b.N; i++ {
- fn.fn(key, 0, data)
- }
- b.SetBytes(int64(len(data)))
- })
- }
- })
- }
- })
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/prepared_test.go b/vendor/github.com/gorilla/websocket/prepared_test.go
deleted file mode 100644
index cf98c6c10..000000000
--- a/vendor/github.com/gorilla/websocket/prepared_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 The Gorilla WebSocket 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 websocket
-
-import (
- "bytes"
- "compress/flate"
- "math/rand"
- "testing"
-)
-
-var preparedMessageTests = []struct {
- messageType int
- isServer bool
- enableWriteCompression bool
- compressionLevel int
-}{
- // Server
- {TextMessage, true, false, flate.BestSpeed},
- {TextMessage, true, true, flate.BestSpeed},
- {TextMessage, true, true, flate.BestCompression},
- {PingMessage, true, false, flate.BestSpeed},
- {PingMessage, true, true, flate.BestSpeed},
-
- // Client
- {TextMessage, false, false, flate.BestSpeed},
- {TextMessage, false, true, flate.BestSpeed},
- {TextMessage, false, true, flate.BestCompression},
- {PingMessage, false, false, flate.BestSpeed},
- {PingMessage, false, true, flate.BestSpeed},
-}
-
-func TestPreparedMessage(t *testing.T) {
- for _, tt := range preparedMessageTests {
- var data = []byte("this is a test")
- var buf bytes.Buffer
- c := newConn(fakeNetConn{Reader: nil, Writer: &buf}, tt.isServer, 1024, 1024)
- if tt.enableWriteCompression {
- c.newCompressionWriter = compressNoContextTakeover
- }
- c.SetCompressionLevel(tt.compressionLevel)
-
- // Seed random number generator for consistent frame mask.
- rand.Seed(1234)
-
- if err := c.WriteMessage(tt.messageType, data); err != nil {
- t.Fatal(err)
- }
- want := buf.String()
-
- pm, err := NewPreparedMessage(tt.messageType, data)
- if err != nil {
- t.Fatal(err)
- }
-
- // Scribble on data to ensure that NewPreparedMessage takes a snapshot.
- copy(data, "hello world")
-
- // Seed random number generator for consistent frame mask.
- rand.Seed(1234)
-
- buf.Reset()
- if err := c.WritePreparedMessage(pm); err != nil {
- t.Fatal(err)
- }
- got := buf.String()
-
- if got != want {
- t.Errorf("write message != prepared message for %+v", tt)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go
index 50b58a893..3e96a00c8 100644
--- a/vendor/github.com/gorilla/websocket/server.go
+++ b/vendor/github.com/gorilla/websocket/server.go
@@ -243,7 +243,7 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
// of the same origin policy check is:
//
// if req.Header.Get("Origin") != "http://"+req.Host {
-// http.Error(w, "Origin not allowed", 403)
+// http.Error(w, "Origin not allowed", http.StatusForbidden)
// return
// }
//
diff --git a/vendor/github.com/gorilla/websocket/server_test.go b/vendor/github.com/gorilla/websocket/server_test.go
deleted file mode 100644
index c43dbb267..000000000
--- a/vendor/github.com/gorilla/websocket/server_test.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket 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 websocket
-
-import (
- "net/http"
- "reflect"
- "testing"
-)
-
-var subprotocolTests = []struct {
- h string
- protocols []string
-}{
- {"", nil},
- {"foo", []string{"foo"}},
- {"foo,bar", []string{"foo", "bar"}},
- {"foo, bar", []string{"foo", "bar"}},
- {" foo, bar", []string{"foo", "bar"}},
- {" foo, bar ", []string{"foo", "bar"}},
-}
-
-func TestSubprotocols(t *testing.T) {
- for _, st := range subprotocolTests {
- r := http.Request{Header: http.Header{"Sec-Websocket-Protocol": {st.h}}}
- protocols := Subprotocols(&r)
- if !reflect.DeepEqual(st.protocols, protocols) {
- t.Errorf("SubProtocols(%q) returned %#v, want %#v", st.h, protocols, st.protocols)
- }
- }
-}
-
-var isWebSocketUpgradeTests = []struct {
- ok bool
- h http.Header
-}{
- {false, http.Header{"Upgrade": {"websocket"}}},
- {false, http.Header{"Connection": {"upgrade"}}},
- {true, http.Header{"Connection": {"upgRade"}, "Upgrade": {"WebSocket"}}},
-}
-
-func TestIsWebSocketUpgrade(t *testing.T) {
- for _, tt := range isWebSocketUpgradeTests {
- ok := IsWebSocketUpgrade(&http.Request{Header: tt.h})
- if tt.ok != ok {
- t.Errorf("IsWebSocketUpgrade(%v) returned %v, want %v", tt.h, ok, tt.ok)
- }
- }
-}
-
-var checkSameOriginTests = []struct {
- ok bool
- r *http.Request
-}{
- {false, &http.Request{Host: "example.org", Header: map[string][]string{"Origin": []string{"https://other.org"}}}},
- {true, &http.Request{Host: "example.org", Header: map[string][]string{"Origin": []string{"https://example.org"}}}},
- {true, &http.Request{Host: "Example.org", Header: map[string][]string{"Origin": []string{"https://example.org"}}}},
-}
-
-func TestCheckSameOrigin(t *testing.T) {
- for _, tt := range checkSameOriginTests {
- ok := checkSameOrigin(tt.r)
- if tt.ok != ok {
- t.Errorf("checkSameOrigin(%+v) returned %v, want %v", tt.r, ok, tt.ok)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/util_test.go b/vendor/github.com/gorilla/websocket/util_test.go
deleted file mode 100644
index 6e15965f5..000000000
--- a/vendor/github.com/gorilla/websocket/util_test.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Gorilla WebSocket 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 websocket
-
-import (
- "net/http"
- "reflect"
- "testing"
-)
-
-var equalASCIIFoldTests = []struct {
- t, s string
- eq bool
-}{
- {"WebSocket", "websocket", true},
- {"websocket", "WebSocket", true},
- {"Öyster", "öyster", false},
-}
-
-func TestEqualASCIIFold(t *testing.T) {
- for _, tt := range equalASCIIFoldTests {
- eq := equalASCIIFold(tt.s, tt.t)
- if eq != tt.eq {
- t.Errorf("equalASCIIFold(%q, %q) = %v, want %v", tt.s, tt.t, eq, tt.eq)
- }
- }
-}
-
-var tokenListContainsValueTests = []struct {
- value string
- ok bool
-}{
- {"WebSocket", true},
- {"WEBSOCKET", true},
- {"websocket", true},
- {"websockets", false},
- {"x websocket", false},
- {"websocket x", false},
- {"other,websocket,more", true},
- {"other, websocket, more", true},
-}
-
-func TestTokenListContainsValue(t *testing.T) {
- for _, tt := range tokenListContainsValueTests {
- h := http.Header{"Upgrade": {tt.value}}
- ok := tokenListContainsValue(h, "Upgrade", "websocket")
- if ok != tt.ok {
- t.Errorf("tokenListContainsValue(h, n, %q) = %v, want %v", tt.value, ok, tt.ok)
- }
- }
-}
-
-var parseExtensionTests = []struct {
- value string
- extensions []map[string]string
-}{
- {`foo`, []map[string]string{{"": "foo"}}},
- {`foo, bar; baz=2`, []map[string]string{
- {"": "foo"},
- {"": "bar", "baz": "2"}}},
- {`foo; bar="b,a;z"`, []map[string]string{
- {"": "foo", "bar": "b,a;z"}}},
- {`foo , bar; baz = 2`, []map[string]string{
- {"": "foo"},
- {"": "bar", "baz": "2"}}},
- {`foo, bar; baz=2 junk`, []map[string]string{
- {"": "foo"}}},
- {`foo junk, bar; baz=2 junk`, nil},
- {`mux; max-channels=4; flow-control, deflate-stream`, []map[string]string{
- {"": "mux", "max-channels": "4", "flow-control": ""},
- {"": "deflate-stream"}}},
- {`permessage-foo; x="10"`, []map[string]string{
- {"": "permessage-foo", "x": "10"}}},
- {`permessage-foo; use_y, permessage-foo`, []map[string]string{
- {"": "permessage-foo", "use_y": ""},
- {"": "permessage-foo"}}},
- {`permessage-deflate; client_max_window_bits; server_max_window_bits=10 , permessage-deflate; client_max_window_bits`, []map[string]string{
- {"": "permessage-deflate", "client_max_window_bits": "", "server_max_window_bits": "10"},
- {"": "permessage-deflate", "client_max_window_bits": ""}}},
- {"permessage-deflate; server_no_context_takeover; client_max_window_bits=15", []map[string]string{
- {"": "permessage-deflate", "server_no_context_takeover": "", "client_max_window_bits": "15"},
- }},
-}
-
-func TestParseExtensions(t *testing.T) {
- for _, tt := range parseExtensionTests {
- h := http.Header{http.CanonicalHeaderKey("Sec-WebSocket-Extensions"): {tt.value}}
- extensions := parseExtensions(h)
- if !reflect.DeepEqual(extensions, tt.extensions) {
- t.Errorf("parseExtensions(%q)\n = %v,\nwant %v", tt.value, extensions, tt.extensions)
- }
- }
-}