summaryrefslogtreecommitdiff
path: root/vendor/github.com/gorilla
diff options
context:
space:
mode:
authorLibravatar Terin Stock <terinjokes@gmail.com>2025-03-09 17:47:56 +0100
committerLibravatar Terin Stock <terinjokes@gmail.com>2025-03-10 01:59:49 +0100
commit3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch)
treef61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/gorilla
parent[chore] update URLs to forked source (diff)
downloadgotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/gorilla')
-rw-r--r--vendor/github.com/gorilla/context/.editorconfig20
-rw-r--r--vendor/github.com/gorilla/context/.gitignore1
-rw-r--r--vendor/github.com/gorilla/context/.golangci.yml12
-rw-r--r--vendor/github.com/gorilla/context/LICENSE27
-rw-r--r--vendor/github.com/gorilla/context/Makefile52
-rw-r--r--vendor/github.com/gorilla/context/README.md26
-rw-r--r--vendor/github.com/gorilla/context/context.go139
-rw-r--r--vendor/github.com/gorilla/context/doc.go88
-rw-r--r--vendor/github.com/gorilla/css/LICENSE28
-rw-r--r--vendor/github.com/gorilla/css/scanner/doc.go33
-rw-r--r--vendor/github.com/gorilla/css/scanner/scanner.go360
-rw-r--r--vendor/github.com/gorilla/feeds/.editorconfig20
-rw-r--r--vendor/github.com/gorilla/feeds/.gitignore1
-rw-r--r--vendor/github.com/gorilla/feeds/LICENSE28
-rw-r--r--vendor/github.com/gorilla/feeds/Makefile34
-rw-r--r--vendor/github.com/gorilla/feeds/README.md198
-rw-r--r--vendor/github.com/gorilla/feeds/atom.go178
-rw-r--r--vendor/github.com/gorilla/feeds/doc.go73
-rw-r--r--vendor/github.com/gorilla/feeds/feed.go146
-rw-r--r--vendor/github.com/gorilla/feeds/json.go190
-rw-r--r--vendor/github.com/gorilla/feeds/rss.go183
-rw-r--r--vendor/github.com/gorilla/feeds/test.atom92
-rw-r--r--vendor/github.com/gorilla/feeds/test.rss96
-rw-r--r--vendor/github.com/gorilla/feeds/to-implement.md20
-rw-r--r--vendor/github.com/gorilla/feeds/uuid.go27
-rw-r--r--vendor/github.com/gorilla/handlers/.editorconfig20
-rw-r--r--vendor/github.com/gorilla/handlers/.gitignore2
-rw-r--r--vendor/github.com/gorilla/handlers/LICENSE27
-rw-r--r--vendor/github.com/gorilla/handlers/Makefile34
-rw-r--r--vendor/github.com/gorilla/handlers/README.md56
-rw-r--r--vendor/github.com/gorilla/handlers/canonical.go73
-rw-r--r--vendor/github.com/gorilla/handlers/compress.go143
-rw-r--r--vendor/github.com/gorilla/handlers/cors.go352
-rw-r--r--vendor/github.com/gorilla/handlers/doc.go9
-rw-r--r--vendor/github.com/gorilla/handlers/handlers.go150
-rw-r--r--vendor/github.com/gorilla/handlers/logging.go246
-rw-r--r--vendor/github.com/gorilla/handlers/proxy_headers.go120
-rw-r--r--vendor/github.com/gorilla/handlers/recovery.go98
-rw-r--r--vendor/github.com/gorilla/securecookie/.editorconfig20
-rw-r--r--vendor/github.com/gorilla/securecookie/.gitignore1
-rw-r--r--vendor/github.com/gorilla/securecookie/LICENSE27
-rw-r--r--vendor/github.com/gorilla/securecookie/Makefile39
-rw-r--r--vendor/github.com/gorilla/securecookie/README.md144
-rw-r--r--vendor/github.com/gorilla/securecookie/doc.go61
-rw-r--r--vendor/github.com/gorilla/securecookie/securecookie.go649
-rw-r--r--vendor/github.com/gorilla/sessions/.editorconfig20
-rw-r--r--vendor/github.com/gorilla/sessions/.gitignore1
-rw-r--r--vendor/github.com/gorilla/sessions/LICENSE27
-rw-r--r--vendor/github.com/gorilla/sessions/Makefile34
-rw-r--r--vendor/github.com/gorilla/sessions/README.md95
-rw-r--r--vendor/github.com/gorilla/sessions/cookie.go20
-rw-r--r--vendor/github.com/gorilla/sessions/cookie_go111.go21
-rw-r--r--vendor/github.com/gorilla/sessions/doc.go207
-rw-r--r--vendor/github.com/gorilla/sessions/lex.go102
-rw-r--r--vendor/github.com/gorilla/sessions/options.go19
-rw-r--r--vendor/github.com/gorilla/sessions/options_go111.go23
-rw-r--r--vendor/github.com/gorilla/sessions/sessions.go218
-rw-r--r--vendor/github.com/gorilla/sessions/store.go291
-rw-r--r--vendor/github.com/gorilla/websocket/.gitignore25
-rw-r--r--vendor/github.com/gorilla/websocket/AUTHORS9
-rw-r--r--vendor/github.com/gorilla/websocket/LICENSE22
-rw-r--r--vendor/github.com/gorilla/websocket/README.md33
-rw-r--r--vendor/github.com/gorilla/websocket/client.go434
-rw-r--r--vendor/github.com/gorilla/websocket/compression.go148
-rw-r--r--vendor/github.com/gorilla/websocket/conn.go1238
-rw-r--r--vendor/github.com/gorilla/websocket/doc.go227
-rw-r--r--vendor/github.com/gorilla/websocket/join.go42
-rw-r--r--vendor/github.com/gorilla/websocket/json.go60
-rw-r--r--vendor/github.com/gorilla/websocket/mask.go55
-rw-r--r--vendor/github.com/gorilla/websocket/mask_safe.go16
-rw-r--r--vendor/github.com/gorilla/websocket/prepared.go102
-rw-r--r--vendor/github.com/gorilla/websocket/proxy.go77
-rw-r--r--vendor/github.com/gorilla/websocket/server.go365
-rw-r--r--vendor/github.com/gorilla/websocket/tls_handshake.go21
-rw-r--r--vendor/github.com/gorilla/websocket/tls_handshake_116.go21
-rw-r--r--vendor/github.com/gorilla/websocket/util.go298
-rw-r--r--vendor/github.com/gorilla/websocket/x_net_proxy.go473
77 files changed, 0 insertions, 9087 deletions
diff --git a/vendor/github.com/gorilla/context/.editorconfig b/vendor/github.com/gorilla/context/.editorconfig
deleted file mode 100644
index 2940ec92a..000000000
--- a/vendor/github.com/gorilla/context/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-; https://editorconfig.org/
-
-root = true
-
-[*]
-insert_final_newline = true
-charset = utf-8
-trim_trailing_whitespace = true
-indent_style = space
-indent_size = 2
-
-[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
-indent_style = tab
-indent_size = 4
-
-[*.md]
-indent_size = 4
-trim_trailing_whitespace = false
-
-eclint_indent_style = unset
diff --git a/vendor/github.com/gorilla/context/.gitignore b/vendor/github.com/gorilla/context/.gitignore
deleted file mode 100644
index 84039fec6..000000000
--- a/vendor/github.com/gorilla/context/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-coverage.coverprofile
diff --git a/vendor/github.com/gorilla/context/.golangci.yml b/vendor/github.com/gorilla/context/.golangci.yml
deleted file mode 100644
index 1def5e627..000000000
--- a/vendor/github.com/gorilla/context/.golangci.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-linters:
- enable:
- - errcheck
- - gosimple
- - govet
- - ineffassign
- - staticcheck
- - unused
- - contextcheck
- - goconst
- - gofmt
- - misspell
diff --git a/vendor/github.com/gorilla/context/LICENSE b/vendor/github.com/gorilla/context/LICENSE
deleted file mode 100644
index f2f8749bc..000000000
--- a/vendor/github.com/gorilla/context/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012-2023 The Gorilla web toolkit authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gorilla/context/Makefile b/vendor/github.com/gorilla/context/Makefile
deleted file mode 100644
index c02b8a41f..000000000
--- a/vendor/github.com/gorilla/context/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
-GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
-
-GO_SEC=$(shell which gosec 2> /dev/null || echo '')
-GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
-
-GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
-GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
-
-.PHONY: golangci-lint
-golangci-lint: ## Run golangci-lint. Example: make golangci-lint
- $(if $(GO_LINT), ,go install $(GO_LINT_URI))
- @echo "##### Running golangci-lint #####"
- golangci-lint run -v
-
-.PHONY: verify
-verify: ## Run all verifications [golangci-lint]. Example: make verify
- @echo "##### Running verifications #####"
- $(MAKE) golangci-lint
-
-.PHONY: gosec
-gosec: ## Run gosec. Example: make gosec
- $(if $(GO_SEC), ,go install $(GO_SEC_URI))
- @echo "##### Running gosec #####"
- gosec ./...
-
-.PHONY: govulncheck
-govulncheck: ## Run govulncheck. Example: make govulncheck
- $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
- @echo "##### Running govulncheck #####"
- govulncheck ./...
-
-.PHONY: security
-security: ## Run all security checks [gosec, govulncheck]. Example: make security
- @echo "##### Running security checks #####"
- $(MAKE) gosec
- $(MAKE) govulncheck
-
-.PHONY: test-unit
-test-unit: ## Run unit tests. Example: make test-unit
- @echo "##### Running unit tests #####"
- go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
-
-.PHONY: test
-test: ## Run all tests [test-unit]. Example: make test
- @echo "##### Running tests #####"
- $(MAKE) test-unit
-
-.PHONY: help
-help: ## Print this help. Example: make help
- @echo "##### Printing help #####"
- @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
diff --git a/vendor/github.com/gorilla/context/README.md b/vendor/github.com/gorilla/context/README.md
deleted file mode 100644
index 6fb5fb049..000000000
--- a/vendor/github.com/gorilla/context/README.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# gorilla/context
-
-[![License](https://img.shields.io/github/license/gorilla/.github)](https://img.shields.io/github/license/gorilla/.github)
-![testing](https://github.com/gorilla/context/actions/workflows/test.yml/badge.svg)
-[![codecov](https://codecov.io/github/gorilla/context/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/context)
-[![godoc](https://godoc.org/github.com/gorilla/context?status.svg)](https://godoc.org/github.com/gorilla/context)
-[![sourcegraph](https://sourcegraph.com/github.com/gorilla/context/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/context?badge)
-[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/7656/badge)](https://bestpractices.coreinfrastructure.org/projects/7656)
-
-![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5)
-
-> ⚠⚠⚠ **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.
->
-> Using gorilla/context may lead to memory leaks under those conditions, as the pointers to each `http.Request` become "islanded" and will not be cleaned up when the response is sent.
->
-> You should use the `http.Request.Context()` feature in Go 1.7.
-
-gorilla/context is a general purpose registry for global request variables.
-
-* It stores a `map[*http.Request]map[interface{}]interface{}` as a global singleton, and thus tracks variables by their HTTP request.
-
-
-### License
-
-See the LICENSE file for details.
diff --git a/vendor/github.com/gorilla/context/context.go b/vendor/github.com/gorilla/context/context.go
deleted file mode 100644
index 9160564dd..000000000
--- a/vendor/github.com/gorilla/context/context.go
+++ /dev/null
@@ -1,139 +0,0 @@
-package context
-
-import (
- "net/http"
- "sync"
- "time"
-)
-
-var (
- mutex sync.RWMutex
- data = make(map[*http.Request]map[interface{}]interface{})
- datat = make(map[*http.Request]int64)
-)
-
-// Set stores a value for a given key in a given request.
-func Set(r *http.Request, key, val interface{}) {
- mutex.Lock()
- if data[r] == nil {
- data[r] = make(map[interface{}]interface{})
- datat[r] = time.Now().Unix()
- }
- data[r][key] = val
- mutex.Unlock()
-}
-
-// Get returns a value stored for a given key in a given request.
-func Get(r *http.Request, key interface{}) interface{} {
- mutex.RLock()
- if ctx := data[r]; ctx != nil {
- value := ctx[key]
- mutex.RUnlock()
- return value
- }
- mutex.RUnlock()
- return nil
-}
-
-// GetOk returns stored value and presence state like multi-value return of map access.
-func GetOk(r *http.Request, key interface{}) (interface{}, bool) {
- mutex.RLock()
- if _, ok := data[r]; ok {
- value, ok := data[r][key]
- mutex.RUnlock()
- return value, ok
- }
- mutex.RUnlock()
- return nil, false
-}
-
-// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests.
-func GetAll(r *http.Request) map[interface{}]interface{} {
- mutex.RLock()
- if context, ok := data[r]; ok {
- result := make(map[interface{}]interface{}, len(context))
- for k, v := range context {
- result[k] = v
- }
- mutex.RUnlock()
- return result
- }
- mutex.RUnlock()
- return nil
-}
-
-// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if
-// the request was registered.
-func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) {
- mutex.RLock()
- context, ok := data[r]
- result := make(map[interface{}]interface{}, len(context))
- for k, v := range context {
- result[k] = v
- }
- mutex.RUnlock()
- return result, ok
-}
-
-// Delete removes a value stored for a given key in a given request.
-func Delete(r *http.Request, key interface{}) {
- mutex.Lock()
- if data[r] != nil {
- delete(data[r], key)
- }
- mutex.Unlock()
-}
-
-// Clear removes all values stored for a given request.
-//
-// This is usually called by a handler wrapper to clean up request
-// variables at the end of a request lifetime. See ClearHandler().
-func Clear(r *http.Request) {
- mutex.Lock()
- clear(r)
- mutex.Unlock()
-}
-
-// clear is Clear without the lock.
-func clear(r *http.Request) {
- delete(data, r)
- delete(datat, r)
-}
-
-// Purge removes request data stored for longer than maxAge, in seconds.
-// It returns the amount of requests removed.
-//
-// If maxAge <= 0, all request data is removed.
-//
-// This is only used for sanity check: in case context cleaning was not
-// properly set some request data can be kept forever, consuming an increasing
-// amount of memory. In case this is detected, Purge() must be called
-// periodically until the problem is fixed.
-func Purge(maxAge int) int {
- mutex.Lock()
- count := 0
- if maxAge <= 0 {
- count = len(data)
- data = make(map[*http.Request]map[interface{}]interface{})
- datat = make(map[*http.Request]int64)
- } else {
- min := time.Now().Unix() - int64(maxAge)
- for r := range data {
- if datat[r] < min {
- clear(r)
- count++
- }
- }
- }
- mutex.Unlock()
- return count
-}
-
-// ClearHandler wraps an http.Handler and clears request values at the end
-// of a request lifetime.
-func ClearHandler(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- defer Clear(r)
- h.ServeHTTP(w, r)
- })
-}
diff --git a/vendor/github.com/gorilla/context/doc.go b/vendor/github.com/gorilla/context/doc.go
deleted file mode 100644
index 448d1bfca..000000000
--- a/vendor/github.com/gorilla/context/doc.go
+++ /dev/null
@@ -1,88 +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 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
-others common uses.
-
-The idea was posted by Brad Fitzpatrick to the go-nuts mailing list:
-
- http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53
-
-Here's the basic usage: first define the keys that you will need. The key
-type is interface{} so a key can be of any type that supports equality.
-Here we define a key using a custom int type to avoid name collisions:
-
- package foo
-
- import (
- "github.com/gorilla/context"
- )
-
- type key int
-
- const MyKey key = 0
-
-Then set a variable. Variables are bound to an http.Request object, so you
-need a request instance to set a value:
-
- context.Set(r, MyKey, "bar")
-
-The application can later access the variable using the same key you provided:
-
- func MyHandler(w http.ResponseWriter, r *http.Request) {
- // val is "bar".
- val := context.Get(r, foo.MyKey)
-
- // returns ("bar", true)
- val, ok := context.GetOk(r, foo.MyKey)
- // ...
- }
-
-And that's all about the basic usage. We discuss some other ideas below.
-
-Any type can be stored in the context. To enforce a given type, make the key
-private and wrap Get() and Set() to accept and return values of a specific
-type:
-
- type key int
-
- const mykey key = 0
-
- // GetMyKey returns a value for this package from the request values.
- func GetMyKey(r *http.Request) SomeType {
- if rv := context.Get(r, mykey); rv != nil {
- return rv.(SomeType)
- }
- return nil
- }
-
- // SetMyKey sets a value for this package in the request values.
- func SetMyKey(r *http.Request, val SomeType) {
- context.Set(r, mykey, val)
- }
-
-Variables must be cleared at the end of a request, to remove all values
-that were stored. This can be done in an http.Handler, after a request was
-served. Just call Clear() passing the request:
-
- context.Clear(r)
-
-...or use ClearHandler(), which conveniently wraps an http.Handler to clear
-variables at the end of a request lifetime.
-
-The Routers from the packages gorilla/mux and gorilla/pat call Clear()
-so if you are using either of them you don't need to clear the context manually.
-*/
-package context
diff --git a/vendor/github.com/gorilla/css/LICENSE b/vendor/github.com/gorilla/css/LICENSE
deleted file mode 100644
index ee0d53cef..000000000
--- a/vendor/github.com/gorilla/css/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2023 The Gorilla Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/vendor/github.com/gorilla/css/scanner/doc.go b/vendor/github.com/gorilla/css/scanner/doc.go
deleted file mode 100644
index f19850e15..000000000
--- a/vendor/github.com/gorilla/css/scanner/doc.go
+++ /dev/null
@@ -1,33 +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 gorilla/css/scanner generates tokens for a CSS3 input.
-
-It follows the CSS3 specification located at:
-
- http://www.w3.org/TR/css3-syntax/
-
-To use it, create a new scanner for a given CSS string and call Next() until
-the token returned has type TokenEOF or TokenError:
-
- s := scanner.New(myCSS)
- for {
- token := s.Next()
- if token.Type == scanner.TokenEOF || token.Type == scanner.TokenError {
- break
- }
- // Do something with the token...
- }
-
-Following the CSS3 specification, an error can only occur when the scanner
-finds an unclosed quote or unclosed comment. In these cases the text becomes
-"untokenizable". Everything else is tokenizable and it is up to a parser
-to make sense of the token stream (or ignore nonsensical token sequences).
-
-Note: the scanner doesn't perform lexical analysis or, in other words, it
-doesn't care about the token context. It is intended to be used by a
-lexer or parser.
-*/
-package scanner
diff --git a/vendor/github.com/gorilla/css/scanner/scanner.go b/vendor/github.com/gorilla/css/scanner/scanner.go
deleted file mode 100644
index 25a7c6576..000000000
--- a/vendor/github.com/gorilla/css/scanner/scanner.go
+++ /dev/null
@@ -1,360 +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 scanner
-
-import (
- "fmt"
- "regexp"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// tokenType identifies the type of lexical tokens.
-type tokenType int
-
-// String returns a string representation of the token type.
-func (t tokenType) String() string {
- return tokenNames[t]
-}
-
-// Token represents a token and the corresponding string.
-type Token struct {
- Type tokenType
- Value string
- Line int
- Column int
-}
-
-// String returns a string representation of the token.
-func (t *Token) String() string {
- if len(t.Value) > 10 {
- return fmt.Sprintf("%s (line: %d, column: %d): %.10q...",
- t.Type, t.Line, t.Column, t.Value)
- }
- return fmt.Sprintf("%s (line: %d, column: %d): %q",
- t.Type, t.Line, t.Column, t.Value)
-}
-
-// All tokens -----------------------------------------------------------------
-
-// The complete list of tokens in CSS3.
-const (
- // Scanner flags.
- TokenError tokenType = iota
- TokenEOF
- // From now on, only tokens from the CSS specification.
- TokenIdent
- TokenAtKeyword
- TokenString
- TokenHash
- TokenNumber
- TokenPercentage
- TokenDimension
- TokenURI
- TokenUnicodeRange
- TokenCDO
- TokenCDC
- TokenS
- TokenComment
- TokenFunction
- TokenIncludes
- TokenDashMatch
- TokenPrefixMatch
- TokenSuffixMatch
- TokenSubstringMatch
- TokenChar
- TokenBOM
-)
-
-// tokenNames maps tokenType's to their names. Used for conversion to string.
-var tokenNames = map[tokenType]string{
- TokenError: "error",
- TokenEOF: "EOF",
- TokenIdent: "IDENT",
- TokenAtKeyword: "ATKEYWORD",
- TokenString: "STRING",
- TokenHash: "HASH",
- TokenNumber: "NUMBER",
- TokenPercentage: "PERCENTAGE",
- TokenDimension: "DIMENSION",
- TokenURI: "URI",
- TokenUnicodeRange: "UNICODE-RANGE",
- TokenCDO: "CDO",
- TokenCDC: "CDC",
- TokenS: "S",
- TokenComment: "COMMENT",
- TokenFunction: "FUNCTION",
- TokenIncludes: "INCLUDES",
- TokenDashMatch: "DASHMATCH",
- TokenPrefixMatch: "PREFIXMATCH",
- TokenSuffixMatch: "SUFFIXMATCH",
- TokenSubstringMatch: "SUBSTRINGMATCH",
- TokenChar: "CHAR",
- TokenBOM: "BOM",
-}
-
-// Macros and productions -----------------------------------------------------
-// http://www.w3.org/TR/css3-syntax/#tokenization
-
-var macroRegexp = regexp.MustCompile(`\{[a-z]+\}`)
-
-// macros maps macro names to patterns to be expanded.
-var macros = map[string]string{
- // must be escaped: `\.+*?()|[]{}^$`
- "ident": `-?{nmstart}{nmchar}*`,
- "name": `{nmchar}+`,
- "nmstart": `[a-zA-Z_]|{nonascii}|{escape}`,
- "nonascii": "[\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF]",
- "unicode": `\\[0-9a-fA-F]{1,6}{wc}?`,
- "escape": "{unicode}|\\\\[\u0020-\u007E\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF]",
- "nmchar": `[a-zA-Z0-9_-]|{nonascii}|{escape}`,
- "num": `[0-9]*\.[0-9]+|[0-9]+`,
- "string": `"(?:{stringchar}|')*"|'(?:{stringchar}|")*'`,
- "stringchar": `{urlchar}|[ ]|\\{nl}`,
- "nl": `[\n\r\f]|\r\n`,
- "w": `{wc}*`,
- "wc": `[\t\n\f\r ]`,
-
- // urlchar should accept [(ascii characters minus those that need escaping)|{nonascii}|{escape}]
- // ASCII characters range = `[\u0020-\u007e]`
- // Skip space \u0020 = `[\u0021-\u007e]`
- // Skip quotation mark \0022 = `[\u0021\u0023-\u007e]`
- // Skip apostrophe \u0027 = `[\u0021\u0023-\u0026\u0028-\u007e]`
- // Skip reverse solidus \u005c = `[\u0021\u0023-\u0026\u0028-\u005b\u005d\u007e]`
- // Finally, the left square bracket (\u005b) and right (\u005d) needs escaping themselves
- "urlchar": "[\u0021\u0023-\u0026\u0028-\\\u005b\\\u005d-\u007E]|{nonascii}|{escape}",
-}
-
-// productions maps the list of tokens to patterns to be expanded.
-var productions = map[tokenType]string{
- // Unused regexps (matched using other methods) are commented out.
- TokenIdent: `{ident}`,
- TokenAtKeyword: `@{ident}`,
- TokenString: `{string}`,
- TokenHash: `#{name}`,
- TokenNumber: `{num}`,
- TokenPercentage: `{num}%`,
- TokenDimension: `{num}{ident}`,
- TokenURI: `url\({w}(?:{string}|{urlchar}*?){w}\)`,
- TokenUnicodeRange: `U\+[0-9A-F\?]{1,6}(?:-[0-9A-F]{1,6})?`,
- //TokenCDO: `<!--`,
- TokenCDC: `-->`,
- TokenS: `{wc}+`,
- TokenComment: `/\*[^\*]*[\*]+(?:[^/][^\*]*[\*]+)*/`,
- TokenFunction: `{ident}\(`,
- //TokenIncludes: `~=`,
- //TokenDashMatch: `\|=`,
- //TokenPrefixMatch: `\^=`,
- //TokenSuffixMatch: `\$=`,
- //TokenSubstringMatch: `\*=`,
- //TokenChar: `[^"']`,
- //TokenBOM: "\uFEFF",
-}
-
-// matchers maps the list of tokens to compiled regular expressions.
-//
-// The map is filled on init() using the macros and productions defined in
-// the CSS specification.
-var matchers = map[tokenType]*regexp.Regexp{}
-
-// matchOrder is the order to test regexps when first-char shortcuts
-// can't be used.
-var matchOrder = []tokenType{
- TokenURI,
- TokenFunction,
- TokenUnicodeRange,
- TokenIdent,
- TokenDimension,
- TokenPercentage,
- TokenNumber,
- TokenCDC,
-}
-
-func init() {
- // replace macros and compile regexps for productions.
- replaceMacro := func(s string) string {
- return "(?:" + macros[s[1:len(s)-1]] + ")"
- }
- for t, s := range productions {
- for macroRegexp.MatchString(s) {
- s = macroRegexp.ReplaceAllStringFunc(s, replaceMacro)
- }
- matchers[t] = regexp.MustCompile("^(?:" + s + ")")
- }
-}
-
-// Scanner --------------------------------------------------------------------
-
-// New returns a new CSS scanner for the given input.
-func New(input string) *Scanner {
- // Normalize newlines.
- // https://www.w3.org/TR/css-syntax-3/#input-preprocessing
- input = strings.Replace(input, "\r\n", "\n", -1)
- input = strings.Replace(input, "\r", "\n", -1)
- input = strings.Replace(input, "\f", "\n", -1)
- input = strings.Replace(input, "\u0000", "\ufffd", -1)
- return &Scanner{
- input: input,
- row: 1,
- col: 1,
- }
-}
-
-// Scanner scans an input and emits tokens following the CSS3 specification.
-type Scanner struct {
- input string
- pos int
- row int
- col int
- err *Token
-}
-
-// Next returns the next token from the input.
-//
-// At the end of the input the token type is TokenEOF.
-//
-// If the input can't be tokenized the token type is TokenError. This occurs
-// in case of unclosed quotation marks or comments.
-func (s *Scanner) Next() *Token {
- if s.err != nil {
- return s.err
- }
- if s.pos >= len(s.input) {
- s.err = &Token{TokenEOF, "", s.row, s.col}
- return s.err
- }
- if s.pos == 0 {
- // Test BOM only once, at the beginning of the file.
- if strings.HasPrefix(s.input, "\uFEFF") {
- return s.emitSimple(TokenBOM, "\uFEFF")
- }
- }
- // There's a lot we can guess based on the first byte so we'll take a
- // shortcut before testing multiple regexps.
- input := s.input[s.pos:]
- switch input[0] {
- case '\t', '\n', ' ':
- // Whitespace.
- return s.emitToken(TokenS, matchers[TokenS].FindString(input))
- case '.':
- // Dot is too common to not have a quick check.
- // We'll test if this is a Char; if it is followed by a number it is a
- // dimension/percentage/number, and this will be matched later.
- if len(input) > 1 && !unicode.IsDigit(rune(input[1])) {
- return s.emitSimple(TokenChar, ".")
- }
- case '#':
- // Another common one: Hash or Char.
- if match := matchers[TokenHash].FindString(input); match != "" {
- return s.emitToken(TokenHash, match)
- }
- return s.emitSimple(TokenChar, "#")
- case '@':
- // Another common one: AtKeyword or Char.
- if match := matchers[TokenAtKeyword].FindString(input); match != "" {
- return s.emitSimple(TokenAtKeyword, match)
- }
- return s.emitSimple(TokenChar, "@")
- case ':', ',', ';', '%', '&', '+', '=', '>', '(', ')', '[', ']', '{', '}':
- // More common chars.
- return s.emitSimple(TokenChar, string(input[0]))
- case '"', '\'':
- // String or error.
- match := matchers[TokenString].FindString(input)
- if match != "" {
- return s.emitToken(TokenString, match)
- }
-
- s.err = &Token{TokenError, "unclosed quotation mark", s.row, s.col}
- return s.err
- case '/':
- // Comment, error or Char.
- if len(input) > 1 && input[1] == '*' {
- match := matchers[TokenComment].FindString(input)
- if match != "" {
- return s.emitToken(TokenComment, match)
- } else {
- s.err = &Token{TokenError, "unclosed comment", s.row, s.col}
- return s.err
- }
- }
- return s.emitSimple(TokenChar, "/")
- case '~':
- // Includes or Char.
- return s.emitPrefixOrChar(TokenIncludes, "~=")
- case '|':
- // DashMatch or Char.
- return s.emitPrefixOrChar(TokenDashMatch, "|=")
- case '^':
- // PrefixMatch or Char.
- return s.emitPrefixOrChar(TokenPrefixMatch, "^=")
- case '$':
- // SuffixMatch or Char.
- return s.emitPrefixOrChar(TokenSuffixMatch, "$=")
- case '*':
- // SubstringMatch or Char.
- return s.emitPrefixOrChar(TokenSubstringMatch, "*=")
- case '<':
- // CDO or Char.
- return s.emitPrefixOrChar(TokenCDO, "<!--")
- }
- // Test all regexps, in order.
- for _, token := range matchOrder {
- if match := matchers[token].FindString(input); match != "" {
- return s.emitToken(token, match)
- }
- }
- // We already handled unclosed quotation marks and comments,
- // so this can only be a Char.
- r, width := utf8.DecodeRuneInString(input)
- token := &Token{TokenChar, string(r), s.row, s.col}
- s.col += width
- s.pos += width
- return token
-}
-
-// updatePosition updates input coordinates based on the consumed text.
-func (s *Scanner) updatePosition(text string) {
- width := utf8.RuneCountInString(text)
- lines := strings.Count(text, "\n")
- s.row += lines
- if lines == 0 {
- s.col += width
- } else {
- s.col = utf8.RuneCountInString(text[strings.LastIndex(text, "\n"):])
- }
- s.pos += len(text) // while col is a rune index, pos is a byte index
-}
-
-// emitToken returns a Token for the string v and updates the scanner position.
-func (s *Scanner) emitToken(t tokenType, v string) *Token {
- token := &Token{t, v, s.row, s.col}
- s.updatePosition(v)
- return token
-}
-
-// emitSimple returns a Token for the string v and updates the scanner
-// position in a simplified manner.
-//
-// The string is known to have only ASCII characters and to not have a newline.
-func (s *Scanner) emitSimple(t tokenType, v string) *Token {
- token := &Token{t, v, s.row, s.col}
- s.col += len(v)
- s.pos += len(v)
- return token
-}
-
-// emitPrefixOrChar returns a Token for type t if the current position
-// matches the given prefix. Otherwise it returns a Char token using the
-// first character from the prefix.
-//
-// The prefix is known to have only ASCII characters and to not have a newline.
-func (s *Scanner) emitPrefixOrChar(t tokenType, prefix string) *Token {
- if strings.HasPrefix(s.input[s.pos:], prefix) {
- return s.emitSimple(t, prefix)
- }
- return s.emitSimple(TokenChar, string(prefix[0]))
-}
diff --git a/vendor/github.com/gorilla/feeds/.editorconfig b/vendor/github.com/gorilla/feeds/.editorconfig
deleted file mode 100644
index 2940ec92a..000000000
--- a/vendor/github.com/gorilla/feeds/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-; https://editorconfig.org/
-
-root = true
-
-[*]
-insert_final_newline = true
-charset = utf-8
-trim_trailing_whitespace = true
-indent_style = space
-indent_size = 2
-
-[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
-indent_style = tab
-indent_size = 4
-
-[*.md]
-indent_size = 4
-trim_trailing_whitespace = false
-
-eclint_indent_style = unset
diff --git a/vendor/github.com/gorilla/feeds/.gitignore b/vendor/github.com/gorilla/feeds/.gitignore
deleted file mode 100644
index 84039fec6..000000000
--- a/vendor/github.com/gorilla/feeds/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-coverage.coverprofile
diff --git a/vendor/github.com/gorilla/feeds/LICENSE b/vendor/github.com/gorilla/feeds/LICENSE
deleted file mode 100644
index ee0d53cef..000000000
--- a/vendor/github.com/gorilla/feeds/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2023 The Gorilla Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/vendor/github.com/gorilla/feeds/Makefile b/vendor/github.com/gorilla/feeds/Makefile
deleted file mode 100644
index ac37ffd32..000000000
--- a/vendor/github.com/gorilla/feeds/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
-GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
-
-GO_SEC=$(shell which gosec 2> /dev/null || echo '')
-GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
-
-GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
-GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
-
-.PHONY: golangci-lint
-golangci-lint:
- $(if $(GO_LINT), ,go install $(GO_LINT_URI))
- @echo "##### Running golangci-lint"
- golangci-lint run -v
-
-.PHONY: gosec
-gosec:
- $(if $(GO_SEC), ,go install $(GO_SEC_URI))
- @echo "##### Running gosec"
- gosec ./...
-
-.PHONY: govulncheck
-govulncheck:
- $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
- @echo "##### Running govulncheck"
- govulncheck ./...
-
-.PHONY: verify
-verify: golangci-lint gosec govulncheck
-
-.PHONY: test
-test:
- @echo "##### Running tests"
- go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
diff --git a/vendor/github.com/gorilla/feeds/README.md b/vendor/github.com/gorilla/feeds/README.md
deleted file mode 100644
index 7d7137b46..000000000
--- a/vendor/github.com/gorilla/feeds/README.md
+++ /dev/null
@@ -1,198 +0,0 @@
-## gorilla/feeds
-![testing](https://github.com/gorilla/feeds/actions/workflows/test.yml/badge.svg)
-[![codecov](https://codecov.io/github/gorilla/feeds/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/feeds)
-[![godoc](https://godoc.org/github.com/gorilla/feeds?status.svg)](https://godoc.org/github.com/gorilla/feeds)
-[![sourcegraph](https://sourcegraph.com/github.com/gorilla/feeds/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/feeds?badge)
-
-![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5)
-
-feeds is a web feed generator library for generating RSS, Atom and JSON feeds from Go
-applications.
-
-### Goals
-
- * Provide a simple interface to create both Atom & RSS 2.0 feeds
- * Full support for [Atom][atom], [RSS 2.0][rss], and [JSON Feed Version 1][jsonfeed] spec elements
- * Ability to modify particulars for each spec
-
-[atom]: https://tools.ietf.org/html/rfc4287
-[rss]: http://www.rssboard.org/rss-specification
-[jsonfeed]: https://jsonfeed.org/version/1.1
-
-### Usage
-
-```go
-package main
-
-import (
- "fmt"
- "log"
- "time"
- "github.com/gorilla/feeds"
-)
-
-func main() {
- now := time.Now()
- feed := &feeds.Feed{
- Title: "jmoiron.net blog",
- Link: &feeds.Link{Href: "http://jmoiron.net/blog"},
- Description: "discussion about tech, footie, photos",
- Author: &feeds.Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
- Created: now,
- }
-
- feed.Items = []*feeds.Item{
- &feeds.Item{
- Title: "Limiting Concurrency in Go",
- Link: &feeds.Link{Href: "http://jmoiron.net/blog/limiting-concurrency-in-go/"},
- Description: "A discussion on controlled parallelism in golang",
- Author: &feeds.Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
- Created: now,
- },
- &feeds.Item{
- Title: "Logic-less Template Redux",
- Link: &feeds.Link{Href: "http://jmoiron.net/blog/logicless-template-redux/"},
- Description: "More thoughts on logicless templates",
- Created: now,
- },
- &feeds.Item{
- Title: "Idiomatic Code Reuse in Go",
- Link: &feeds.Link{Href: "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"},
- Description: "How to use interfaces <em>effectively</em>",
- Created: now,
- },
- }
-
- atom, err := feed.ToAtom()
- if err != nil {
- log.Fatal(err)
- }
-
- rss, err := feed.ToRss()
- if err != nil {
- log.Fatal(err)
- }
-
- json, err := feed.ToJSON()
- if err != nil {
- log.Fatal(err)
- }
-
- fmt.Println(atom, "\n", rss, "\n", json)
-}
-```
-
-Outputs:
-
-```xml
-<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title>jmoiron.net blog</title>
- <link href="http://jmoiron.net/blog"></link>
- <id>http://jmoiron.net/blog</id>
- <updated>2013-01-16T03:26:01-05:00</updated>
- <summary>discussion about tech, footie, photos</summary>
- <entry>
- <title>Limiting Concurrency in Go</title>
- <link href="http://jmoiron.net/blog/limiting-concurrency-in-go/"></link>
- <updated>2013-01-16T03:26:01-05:00</updated>
- <id>tag:jmoiron.net,2013-01-16:/blog/limiting-concurrency-in-go/</id>
- <summary type="html">A discussion on controlled parallelism in golang</summary>
- <author>
- <name>Jason Moiron</name>
- <email>jmoiron@jmoiron.net</email>
- </author>
- </entry>
- <entry>
- <title>Logic-less Template Redux</title>
- <link href="http://jmoiron.net/blog/logicless-template-redux/"></link>
- <updated>2013-01-16T03:26:01-05:00</updated>
- <id>tag:jmoiron.net,2013-01-16:/blog/logicless-template-redux/</id>
- <summary type="html">More thoughts on logicless templates</summary>
- <author></author>
- </entry>
- <entry>
- <title>Idiomatic Code Reuse in Go</title>
- <link href="http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"></link>
- <updated>2013-01-16T03:26:01-05:00</updated>
- <id>tag:jmoiron.net,2013-01-16:/blog/idiomatic-code-reuse-in-go/</id>
- <summary type="html">How to use interfaces &lt;em&gt;effectively&lt;/em&gt;</summary>
- <author></author>
- </entry>
-</feed>
-
-<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0">
- <channel>
- <title>jmoiron.net blog</title>
- <link>http://jmoiron.net/blog</link>
- <description>discussion about tech, footie, photos</description>
- <managingEditor>jmoiron@jmoiron.net (Jason Moiron)</managingEditor>
- <pubDate>2013-01-16T03:22:24-05:00</pubDate>
- <item>
- <title>Limiting Concurrency in Go</title>
- <link>http://jmoiron.net/blog/limiting-concurrency-in-go/</link>
- <description>A discussion on controlled parallelism in golang</description>
- <pubDate>2013-01-16T03:22:24-05:00</pubDate>
- </item>
- <item>
- <title>Logic-less Template Redux</title>
- <link>http://jmoiron.net/blog/logicless-template-redux/</link>
- <description>More thoughts on logicless templates</description>
- <pubDate>2013-01-16T03:22:24-05:00</pubDate>
- </item>
- <item>
- <title>Idiomatic Code Reuse in Go</title>
- <link>http://jmoiron.net/blog/idiomatic-code-reuse-in-go/</link>
- <description>How to use interfaces &lt;em&gt;effectively&lt;/em&gt;</description>
- <pubDate>2013-01-16T03:22:24-05:00</pubDate>
- </item>
- </channel>
-</rss>
-
-{
- "version": "https://jsonfeed.org/version/1.1",
- "title": "jmoiron.net blog",
- "home_page_url": "http://jmoiron.net/blog",
- "description": "discussion about tech, footie, photos",
- "author": {
- "name": "Jason Moiron"
- },
- "authors": [
- {
- "name": "Jason Moiron"
- }
- ],
- "items": [
- {
- "id": "",
- "url": "http://jmoiron.net/blog/limiting-concurrency-in-go/",
- "title": "Limiting Concurrency in Go",
- "summary": "A discussion on controlled parallelism in golang",
- "date_published": "2013-01-16T03:22:24.530817846-05:00",
- "author": {
- "name": "Jason Moiron"
- },
- "authors": [
- {
- "name": "Jason Moiron"
- }
- ]
- },
- {
- "id": "",
- "url": "http://jmoiron.net/blog/logicless-template-redux/",
- "title": "Logic-less Template Redux",
- "summary": "More thoughts on logicless templates",
- "date_published": "2013-01-16T03:22:24.530817846-05:00"
- },
- {
- "id": "",
- "url": "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/",
- "title": "Idiomatic Code Reuse in Go",
- "summary": "How to use interfaces \u003cem\u003eeffectively\u003c/em\u003e",
- "date_published": "2013-01-16T03:22:24.530817846-05:00"
- }
- ]
-}
-```
diff --git a/vendor/github.com/gorilla/feeds/atom.go b/vendor/github.com/gorilla/feeds/atom.go
deleted file mode 100644
index 73de995c1..000000000
--- a/vendor/github.com/gorilla/feeds/atom.go
+++ /dev/null
@@ -1,178 +0,0 @@
-package feeds
-
-import (
- "encoding/xml"
- "fmt"
- "net/url"
- "time"
-)
-
-// Generates Atom feed as XML
-
-const ns = "http://www.w3.org/2005/Atom"
-
-type AtomPerson struct {
- Name string `xml:"name,omitempty"`
- Uri string `xml:"uri,omitempty"`
- Email string `xml:"email,omitempty"`
-}
-
-type AtomSummary struct {
- XMLName xml.Name `xml:"summary"`
- Content string `xml:",chardata"`
- Type string `xml:"type,attr"`
-}
-
-type AtomContent struct {
- XMLName xml.Name `xml:"content"`
- Content string `xml:",chardata"`
- Type string `xml:"type,attr"`
-}
-
-type AtomAuthor struct {
- XMLName xml.Name `xml:"author"`
- AtomPerson
-}
-
-type AtomContributor struct {
- XMLName xml.Name `xml:"contributor"`
- AtomPerson
-}
-
-type AtomEntry struct {
- XMLName xml.Name `xml:"entry"`
- Xmlns string `xml:"xmlns,attr,omitempty"`
- Title string `xml:"title"` // required
- Updated string `xml:"updated"` // required
- Id string `xml:"id"` // required
- Category string `xml:"category,omitempty"`
- Content *AtomContent
- Rights string `xml:"rights,omitempty"`
- Source string `xml:"source,omitempty"`
- Published string `xml:"published,omitempty"`
- Contributor *AtomContributor
- Links []AtomLink // required if no child 'content' elements
- Summary *AtomSummary // required if content has src or content is base64
- Author *AtomAuthor // required if feed lacks an author
-}
-
-// Multiple links with different rel can coexist
-type AtomLink struct {
- //Atom 1.0 <link rel="enclosure" type="audio/mpeg" title="MP3" href="http://www.example.org/myaudiofile.mp3" length="1234" />
- XMLName xml.Name `xml:"link"`
- Href string `xml:"href,attr"`
- Rel string `xml:"rel,attr,omitempty"`
- Type string `xml:"type,attr,omitempty"`
- Length string `xml:"length,attr,omitempty"`
-}
-
-type AtomFeed struct {
- XMLName xml.Name `xml:"feed"`
- Xmlns string `xml:"xmlns,attr"`
- Title string `xml:"title"` // required
- Id string `xml:"id"` // required
- Updated string `xml:"updated"` // required
- Category string `xml:"category,omitempty"`
- Icon string `xml:"icon,omitempty"`
- Logo string `xml:"logo,omitempty"`
- Rights string `xml:"rights,omitempty"` // copyright used
- Subtitle string `xml:"subtitle,omitempty"`
- Link *AtomLink
- Author *AtomAuthor `xml:"author,omitempty"`
- Contributor *AtomContributor
- Entries []*AtomEntry `xml:"entry"`
-}
-
-type Atom struct {
- *Feed
-}
-
-func newAtomEntry(i *Item) *AtomEntry {
- id := i.Id
- link := i.Link
- if link == nil {
- link = &Link{}
- }
- if len(id) == 0 {
- // if there's no id set, try to create one, either from data or just a uuid
- if len(link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) {
- dateStr := anyTimeFormat("2006-01-02", i.Updated, i.Created)
- host, path := link.Href, "/invalid.html"
- if url, err := url.Parse(link.Href); err == nil {
- host, path = url.Host, url.Path
- }
- id = fmt.Sprintf("tag:%s,%s:%s", host, dateStr, path)
- } else {
- id = "urn:uuid:" + NewUUID().String()
- }
- }
- var name, email string
- if i.Author != nil {
- name, email = i.Author.Name, i.Author.Email
- }
-
- link_rel := link.Rel
- if link_rel == "" {
- link_rel = "alternate"
- }
- x := &AtomEntry{
- Title: i.Title,
- Links: []AtomLink{{Href: link.Href, Rel: link_rel, Type: link.Type}},
- Id: id,
- Updated: anyTimeFormat(time.RFC3339, i.Updated, i.Created),
- }
-
- // if there's a description, assume it's html
- if len(i.Description) > 0 {
- x.Summary = &AtomSummary{Content: i.Description, Type: "html"}
- }
-
- // if there's a content, assume it's html
- if len(i.Content) > 0 {
- x.Content = &AtomContent{Content: i.Content, Type: "html"}
- }
-
- if i.Enclosure != nil && link_rel != "enclosure" {
- x.Links = append(x.Links, AtomLink{Href: i.Enclosure.Url, Rel: "enclosure", Type: i.Enclosure.Type, Length: i.Enclosure.Length})
- }
-
- if len(name) > 0 || len(email) > 0 {
- x.Author = &AtomAuthor{AtomPerson: AtomPerson{Name: name, Email: email}}
- }
- return x
-}
-
-// create a new AtomFeed with a generic Feed struct's data
-func (a *Atom) AtomFeed() *AtomFeed {
- updated := anyTimeFormat(time.RFC3339, a.Updated, a.Created)
- link := a.Link
- if link == nil {
- link = &Link{}
- }
- feed := &AtomFeed{
- Xmlns: ns,
- Title: a.Title,
- Link: &AtomLink{Href: link.Href, Rel: link.Rel},
- Subtitle: a.Description,
- Id: link.Href,
- Updated: updated,
- Rights: a.Copyright,
- }
- if a.Author != nil {
- feed.Author = &AtomAuthor{AtomPerson: AtomPerson{Name: a.Author.Name, Email: a.Author.Email}}
- }
- for _, e := range a.Items {
- feed.Entries = append(feed.Entries, newAtomEntry(e))
- }
- return feed
-}
-
-// FeedXml returns an XML-Ready object for an Atom object
-func (a *Atom) FeedXml() interface{} {
- return a.AtomFeed()
-}
-
-// FeedXml returns an XML-ready object for an AtomFeed object
-func (a *AtomFeed) FeedXml() interface{} {
- return a
-}
diff --git a/vendor/github.com/gorilla/feeds/doc.go b/vendor/github.com/gorilla/feeds/doc.go
deleted file mode 100644
index 4e0759ccc..000000000
--- a/vendor/github.com/gorilla/feeds/doc.go
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-Syndication (feed) generator library for golang.
-
-Installing
-
- go get github.com/gorilla/feeds
-
-Feeds provides a simple, generic Feed interface with a generic Item object as well as RSS, Atom and JSON Feed specific RssFeed, AtomFeed and JSONFeed objects which allow access to all of each spec's defined elements.
-
-Examples
-
-Create a Feed and some Items in that feed using the generic interfaces:
-
- import (
- "time"
- . "github.com/gorilla/feeds"
- )
-
- now = time.Now()
-
- feed := &Feed{
- Title: "jmoiron.net blog",
- Link: &Link{Href: "http://jmoiron.net/blog"},
- Description: "discussion about tech, footie, photos",
- Author: &Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
- Created: now,
- Copyright: "This work is copyright © Benjamin Button",
- }
-
- feed.Items = []*Item{
- &Item{
- Title: "Limiting Concurrency in Go",
- Link: &Link{Href: "http://jmoiron.net/blog/limiting-concurrency-in-go/"},
- Description: "A discussion on controlled parallelism in golang",
- Author: &Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
- Created: now,
- },
- &Item{
- Title: "Logic-less Template Redux",
- Link: &Link{Href: "http://jmoiron.net/blog/logicless-template-redux/"},
- Description: "More thoughts on logicless templates",
- Created: now,
- },
- &Item{
- Title: "Idiomatic Code Reuse in Go",
- Link: &Link{Href: "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"},
- Description: "How to use interfaces <em>effectively</em>",
- Created: now,
- },
- }
-
-From here, you can output Atom, RSS, or JSON Feed versions of this feed easily
-
- atom, err := feed.ToAtom()
- rss, err := feed.ToRss()
- json, err := feed.ToJSON()
-
-You can also get access to the underlying objects that feeds uses to export its XML
-
- atomFeed := (&Atom{Feed: feed}).AtomFeed()
- rssFeed := (&Rss{Feed: feed}).RssFeed()
- jsonFeed := (&JSON{Feed: feed}).JSONFeed()
-
-From here, you can modify or add each syndication's specific fields before outputting
-
- atomFeed.Subtitle = "plays the blues"
- atom, err := ToXML(atomFeed)
- rssFeed.Generator = "gorilla/feeds v1.0 (github.com/gorilla/feeds)"
- rss, err := ToXML(rssFeed)
- jsonFeed.NextUrl = "https://www.example.com/feed.json?page=2"
- json, err := jsonFeed.ToJSON()
-*/
-package feeds
diff --git a/vendor/github.com/gorilla/feeds/feed.go b/vendor/github.com/gorilla/feeds/feed.go
deleted file mode 100644
index 929c226c0..000000000
--- a/vendor/github.com/gorilla/feeds/feed.go
+++ /dev/null
@@ -1,146 +0,0 @@
-package feeds
-
-import (
- "encoding/json"
- "encoding/xml"
- "io"
- "sort"
- "time"
-)
-
-type Link struct {
- Href, Rel, Type, Length string
-}
-
-type Author struct {
- Name, Email string
-}
-
-type Image struct {
- Url, Title, Link string
- Width, Height int
-}
-
-type Enclosure struct {
- Url, Length, Type string
-}
-
-type Item struct {
- Title string
- Link *Link
- Source *Link
- Author *Author
- Description string // used as description in rss, summary in atom
- Id string // used as guid in rss, id in atom
- IsPermaLink string // an optional parameter for guid in rss
- Updated time.Time
- Created time.Time
- Enclosure *Enclosure
- Content string
-}
-
-type Feed struct {
- Title string
- Link *Link
- Description string
- Author *Author
- Updated time.Time
- Created time.Time
- Id string
- Subtitle string
- Items []*Item
- Copyright string
- Image *Image
-}
-
-// add a new Item to a Feed
-func (f *Feed) Add(item *Item) {
- f.Items = append(f.Items, item)
-}
-
-// returns the first non-zero time formatted as a string or ""
-func anyTimeFormat(format string, times ...time.Time) string {
- for _, t := range times {
- if !t.IsZero() {
- return t.Format(format)
- }
- }
- return ""
-}
-
-// interface used by ToXML to get a object suitable for exporting XML.
-type XmlFeed interface {
- FeedXml() interface{}
-}
-
-// turn a feed object (either a Feed, AtomFeed, or RssFeed) into xml
-// returns an error if xml marshaling fails
-func ToXML(feed XmlFeed) (string, error) {
- x := feed.FeedXml()
- data, err := xml.MarshalIndent(x, "", " ")
- if err != nil {
- return "", err
- }
- // strip empty line from default xml header
- s := xml.Header[:len(xml.Header)-1] + string(data)
- return s, nil
-}
-
-// WriteXML writes a feed object (either a Feed, AtomFeed, or RssFeed) as XML into
-// the writer. Returns an error if XML marshaling fails.
-func WriteXML(feed XmlFeed, w io.Writer) error {
- x := feed.FeedXml()
- // write default xml header, without the newline
- if _, err := w.Write([]byte(xml.Header[:len(xml.Header)-1])); err != nil {
- return err
- }
- e := xml.NewEncoder(w)
- e.Indent("", " ")
- return e.Encode(x)
-}
-
-// creates an Atom representation of this feed
-func (f *Feed) ToAtom() (string, error) {
- a := &Atom{f}
- return ToXML(a)
-}
-
-// WriteAtom writes an Atom representation of this feed to the writer.
-func (f *Feed) WriteAtom(w io.Writer) error {
- return WriteXML(&Atom{f}, w)
-}
-
-// creates an Rss representation of this feed
-func (f *Feed) ToRss() (string, error) {
- r := &Rss{f}
- return ToXML(r)
-}
-
-// WriteRss writes an RSS representation of this feed to the writer.
-func (f *Feed) WriteRss(w io.Writer) error {
- return WriteXML(&Rss{f}, w)
-}
-
-// ToJSON creates a JSON Feed representation of this feed
-func (f *Feed) ToJSON() (string, error) {
- j := &JSON{f}
- return j.ToJSON()
-}
-
-// WriteJSON writes an JSON representation of this feed to the writer.
-func (f *Feed) WriteJSON(w io.Writer) error {
- j := &JSON{f}
- feed := j.JSONFeed()
-
- e := json.NewEncoder(w)
- e.SetIndent("", " ")
- return e.Encode(feed)
-}
-
-// Sort sorts the Items in the feed with the given less function.
-func (f *Feed) Sort(less func(a, b *Item) bool) {
- lessFunc := func(i, j int) bool {
- return less(f.Items[i], f.Items[j])
- }
- sort.SliceStable(f.Items, lessFunc)
-}
diff --git a/vendor/github.com/gorilla/feeds/json.go b/vendor/github.com/gorilla/feeds/json.go
deleted file mode 100644
index ae5deb76d..000000000
--- a/vendor/github.com/gorilla/feeds/json.go
+++ /dev/null
@@ -1,190 +0,0 @@
-package feeds
-
-import (
- "encoding/json"
- "strings"
- "time"
-)
-
-const jsonFeedVersion = "https://jsonfeed.org/version/1.1"
-
-// JSONAuthor represents the author of the feed or of an individual item
-// in the feed
-type JSONAuthor struct {
- Name string `json:"name,omitempty"`
- Url string `json:"url,omitempty"`
- Avatar string `json:"avatar,omitempty"`
-}
-
-// JSONAttachment represents a related resource. Podcasts, for instance, would
-// include an attachment that’s an audio or video file.
-type JSONAttachment struct {
- Url string `json:"url,omitempty"`
- MIMEType string `json:"mime_type,omitempty"`
- Title string `json:"title,omitempty"`
- Size int32 `json:"size,omitempty"`
- Duration time.Duration `json:"duration_in_seconds,omitempty"`
-}
-
-// MarshalJSON implements the json.Marshaler interface.
-// The Duration field is marshaled in seconds, all other fields are marshaled
-// based upon the definitions in struct tags.
-func (a *JSONAttachment) MarshalJSON() ([]byte, error) {
- type EmbeddedJSONAttachment JSONAttachment
- return json.Marshal(&struct {
- Duration float64 `json:"duration_in_seconds,omitempty"`
- *EmbeddedJSONAttachment
- }{
- EmbeddedJSONAttachment: (*EmbeddedJSONAttachment)(a),
- Duration: a.Duration.Seconds(),
- })
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface.
-// The Duration field is expected to be in seconds, all other field types
-// match the struct definition.
-func (a *JSONAttachment) UnmarshalJSON(data []byte) error {
- type EmbeddedJSONAttachment JSONAttachment
- var raw struct {
- Duration float64 `json:"duration_in_seconds,omitempty"`
- *EmbeddedJSONAttachment
- }
- raw.EmbeddedJSONAttachment = (*EmbeddedJSONAttachment)(a)
-
- err := json.Unmarshal(data, &raw)
- if err != nil {
- return err
- }
-
- if raw.Duration > 0 {
- nsec := int64(raw.Duration * float64(time.Second))
- raw.EmbeddedJSONAttachment.Duration = time.Duration(nsec)
- }
-
- return nil
-}
-
-// JSONItem represents a single entry/post for the feed.
-type JSONItem struct {
- Id string `json:"id"`
- Url string `json:"url,omitempty"`
- ExternalUrl string `json:"external_url,omitempty"`
- Title string `json:"title,omitempty"`
- ContentHTML string `json:"content_html,omitempty"`
- ContentText string `json:"content_text,omitempty"`
- Summary string `json:"summary,omitempty"`
- Image string `json:"image,omitempty"`
- BannerImage string `json:"banner_,omitempty"`
- PublishedDate *time.Time `json:"date_published,omitempty"`
- ModifiedDate *time.Time `json:"date_modified,omitempty"`
- Author *JSONAuthor `json:"author,omitempty"` // deprecated in JSON Feed v1.1, keeping for backwards compatibility
- Authors []*JSONAuthor `json:"authors,omitempty"`
- Tags []string `json:"tags,omitempty"`
- Attachments []JSONAttachment `json:"attachments,omitempty"`
-}
-
-// JSONHub describes an endpoint that can be used to subscribe to real-time
-// notifications from the publisher of this feed.
-type JSONHub struct {
- Type string `json:"type"`
- Url string `json:"url"`
-}
-
-// JSONFeed represents a syndication feed in the JSON Feed Version 1 format.
-// Matching the specification found here: https://jsonfeed.org/version/1.
-type JSONFeed struct {
- Version string `json:"version"`
- Title string `json:"title"`
- Language string `json:"language,omitempty"`
- HomePageUrl string `json:"home_page_url,omitempty"`
- FeedUrl string `json:"feed_url,omitempty"`
- Description string `json:"description,omitempty"`
- UserComment string `json:"user_comment,omitempty"`
- NextUrl string `json:"next_url,omitempty"`
- Icon string `json:"icon,omitempty"`
- Favicon string `json:"favicon,omitempty"`
- Author *JSONAuthor `json:"author,omitempty"` // deprecated in JSON Feed v1.1, keeping for backwards compatibility
- Authors []*JSONAuthor `json:"authors,omitempty"`
- Expired *bool `json:"expired,omitempty"`
- Hubs []*JSONHub `json:"hubs,omitempty"`
- Items []*JSONItem `json:"items,omitempty"`
-}
-
-// JSON is used to convert a generic Feed to a JSONFeed.
-type JSON struct {
- *Feed
-}
-
-// ToJSON encodes f into a JSON string. Returns an error if marshalling fails.
-func (f *JSON) ToJSON() (string, error) {
- return f.JSONFeed().ToJSON()
-}
-
-// ToJSON encodes f into a JSON string. Returns an error if marshalling fails.
-func (f *JSONFeed) ToJSON() (string, error) {
- data, err := json.MarshalIndent(f, "", " ")
- if err != nil {
- return "", err
- }
-
- return string(data), nil
-}
-
-// JSONFeed creates a new JSONFeed with a generic Feed struct's data.
-func (f *JSON) JSONFeed() *JSONFeed {
- feed := &JSONFeed{
- Version: jsonFeedVersion,
- Title: f.Title,
- Description: f.Description,
- }
-
- if f.Link != nil {
- feed.HomePageUrl = f.Link.Href
- }
- if f.Author != nil {
- author := &JSONAuthor{
- Name: f.Author.Name,
- }
- feed.Author = author
- feed.Authors = []*JSONAuthor{author}
- }
- for _, e := range f.Items {
- feed.Items = append(feed.Items, newJSONItem(e))
- }
- return feed
-}
-
-func newJSONItem(i *Item) *JSONItem {
- item := &JSONItem{
- Id: i.Id,
- Title: i.Title,
- Summary: i.Description,
-
- ContentHTML: i.Content,
- }
-
- if i.Link != nil {
- item.Url = i.Link.Href
- }
- if i.Source != nil {
- item.ExternalUrl = i.Source.Href
- }
- if i.Author != nil {
- author := &JSONAuthor{
- Name: i.Author.Name,
- }
- item.Author = author
- item.Authors = []*JSONAuthor{author}
- }
- if !i.Created.IsZero() {
- item.PublishedDate = &i.Created
- }
- if !i.Updated.IsZero() {
- item.ModifiedDate = &i.Updated
- }
- if i.Enclosure != nil && strings.HasPrefix(i.Enclosure.Type, "image/") {
- item.Image = i.Enclosure.Url
- }
-
- return item
-}
diff --git a/vendor/github.com/gorilla/feeds/rss.go b/vendor/github.com/gorilla/feeds/rss.go
deleted file mode 100644
index 9326cef8b..000000000
--- a/vendor/github.com/gorilla/feeds/rss.go
+++ /dev/null
@@ -1,183 +0,0 @@
-package feeds
-
-// rss support
-// validation done according to spec here:
-// http://cyber.law.harvard.edu/rss/rss.html
-
-import (
- "encoding/xml"
- "fmt"
- "time"
-)
-
-// private wrapper around the RssFeed which gives us the <rss>..</rss> xml
-type RssFeedXml struct {
- XMLName xml.Name `xml:"rss"`
- Version string `xml:"version,attr"`
- ContentNamespace string `xml:"xmlns:content,attr"`
- Channel *RssFeed
-}
-
-type RssContent struct {
- XMLName xml.Name `xml:"content:encoded"`
- Content string `xml:",cdata"`
-}
-
-type RssImage struct {
- XMLName xml.Name `xml:"image"`
- Url string `xml:"url"`
- Title string `xml:"title"`
- Link string `xml:"link"`
- Width int `xml:"width,omitempty"`
- Height int `xml:"height,omitempty"`
-}
-
-type RssTextInput struct {
- XMLName xml.Name `xml:"textInput"`
- Title string `xml:"title"`
- Description string `xml:"description"`
- Name string `xml:"name"`
- Link string `xml:"link"`
-}
-
-type RssFeed struct {
- XMLName xml.Name `xml:"channel"`
- Title string `xml:"title"` // required
- Link string `xml:"link"` // required
- Description string `xml:"description"` // required
- Language string `xml:"language,omitempty"`
- Copyright string `xml:"copyright,omitempty"`
- ManagingEditor string `xml:"managingEditor,omitempty"` // Author used
- WebMaster string `xml:"webMaster,omitempty"`
- PubDate string `xml:"pubDate,omitempty"` // created or updated
- LastBuildDate string `xml:"lastBuildDate,omitempty"` // updated used
- Category string `xml:"category,omitempty"`
- Generator string `xml:"generator,omitempty"`
- Docs string `xml:"docs,omitempty"`
- Cloud string `xml:"cloud,omitempty"`
- Ttl int `xml:"ttl,omitempty"`
- Rating string `xml:"rating,omitempty"`
- SkipHours string `xml:"skipHours,omitempty"`
- SkipDays string `xml:"skipDays,omitempty"`
- Image *RssImage
- TextInput *RssTextInput
- Items []*RssItem `xml:"item"`
-}
-
-type RssItem struct {
- XMLName xml.Name `xml:"item"`
- Title string `xml:"title"` // required
- Link string `xml:"link"` // required
- Description string `xml:"description"` // required
- Content *RssContent
- Author string `xml:"author,omitempty"`
- Category string `xml:"category,omitempty"`
- Comments string `xml:"comments,omitempty"`
- Enclosure *RssEnclosure
- Guid *RssGuid // Id used
- PubDate string `xml:"pubDate,omitempty"` // created or updated
- Source string `xml:"source,omitempty"`
-}
-
-type RssEnclosure struct {
- //RSS 2.0 <enclosure url="http://example.com/file.mp3" length="123456789" type="audio/mpeg" />
- XMLName xml.Name `xml:"enclosure"`
- Url string `xml:"url,attr"`
- Length string `xml:"length,attr"`
- Type string `xml:"type,attr"`
-}
-
-type RssGuid struct {
- //RSS 2.0 <guid isPermaLink="true">http://inessential.com/2002/09/01.php#a2</guid>
- XMLName xml.Name `xml:"guid"`
- Id string `xml:",chardata"`
- IsPermaLink string `xml:"isPermaLink,attr,omitempty"` // "true", "false", or an empty string
-}
-
-type Rss struct {
- *Feed
-}
-
-// create a new RssItem with a generic Item struct's data
-func newRssItem(i *Item) *RssItem {
- item := &RssItem{
- Title: i.Title,
- Description: i.Description,
- PubDate: anyTimeFormat(time.RFC1123Z, i.Created, i.Updated),
- }
- if i.Id != "" {
- item.Guid = &RssGuid{Id: i.Id, IsPermaLink: i.IsPermaLink}
- }
- if i.Link != nil {
- item.Link = i.Link.Href
- }
- if len(i.Content) > 0 {
- item.Content = &RssContent{Content: i.Content}
- }
- if i.Source != nil {
- item.Source = i.Source.Href
- }
-
- // Define a closure
- if i.Enclosure != nil && i.Enclosure.Type != "" && i.Enclosure.Length != "" {
- item.Enclosure = &RssEnclosure{Url: i.Enclosure.Url, Type: i.Enclosure.Type, Length: i.Enclosure.Length}
- }
-
- if i.Author != nil {
- item.Author = i.Author.Name
- }
- return item
-}
-
-// create a new RssFeed with a generic Feed struct's data
-func (r *Rss) RssFeed() *RssFeed {
- pub := anyTimeFormat(time.RFC1123Z, r.Created, r.Updated)
- build := anyTimeFormat(time.RFC1123Z, r.Updated)
- author := ""
- if r.Author != nil {
- author = r.Author.Email
- if len(r.Author.Name) > 0 {
- author = fmt.Sprintf("%s (%s)", r.Author.Email, r.Author.Name)
- }
- }
-
- var image *RssImage
- if r.Image != nil {
- image = &RssImage{Url: r.Image.Url, Title: r.Image.Title, Link: r.Image.Link, Width: r.Image.Width, Height: r.Image.Height}
- }
-
- var href string
- if r.Link != nil {
- href = r.Link.Href
- }
- channel := &RssFeed{
- Title: r.Title,
- Link: href,
- Description: r.Description,
- ManagingEditor: author,
- PubDate: pub,
- LastBuildDate: build,
- Copyright: r.Copyright,
- Image: image,
- }
- for _, i := range r.Items {
- channel.Items = append(channel.Items, newRssItem(i))
- }
- return channel
-}
-
-// FeedXml returns an XML-Ready object for an Rss object
-func (r *Rss) FeedXml() interface{} {
- // only generate version 2.0 feeds for now
- return r.RssFeed().FeedXml()
-
-}
-
-// FeedXml returns an XML-ready object for an RssFeed object
-func (r *RssFeed) FeedXml() interface{} {
- return &RssFeedXml{
- Version: "2.0",
- Channel: r,
- ContentNamespace: "http://purl.org/rss/1.0/modules/content/",
- }
-}
diff --git a/vendor/github.com/gorilla/feeds/test.atom b/vendor/github.com/gorilla/feeds/test.atom
deleted file mode 100644
index aa1521481..000000000
--- a/vendor/github.com/gorilla/feeds/test.atom
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns:atom="http://www.w3.org/2005/Atom">
- <title><![CDATA[Lorem ipsum feed for an interval of 1 minutes]]></title>
- <description><![CDATA[This is a constantly updating lorem ipsum feed]]></description>
- <link>http://example.com/</link>
- <generator>RSS for Node</generator>
- <lastBuildDate>Tue, 30 Oct 2018 23:22:37 GMT</lastBuildDate>
- <author><![CDATA[John Smith]]></author>
- <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
- <copyright><![CDATA[Michael Bertolacci, licensed under a Creative Commons Attribution 3.0 Unported License.]]></copyright>
- <ttl>60</ttl>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:22:00+00:00]]></title>
- <description><![CDATA[Exercitation ut Lorem sint proident.]]></description>
- <link>http://example.com/test/1540941720</link>
- <guid isPermaLink="true">http://example.com/test/1540941720</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:21:00+00:00]]></title>
- <description><![CDATA[Ea est do quis fugiat exercitation.]]></description>
- <link>http://example.com/test/1540941660</link>
- <guid isPermaLink="true">http://example.com/test/1540941660</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:21:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:20:00+00:00]]></title>
- <description><![CDATA[Ipsum velit cillum ad laborum sit nulla exercitation consequat sint veniam culpa veniam voluptate incididunt.]]></description>
- <link>http://example.com/test/1540941600</link>
- <guid isPermaLink="true">http://example.com/test/1540941600</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:20:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:19:00+00:00]]></title>
- <description><![CDATA[Ullamco pariatur aliqua consequat ea veniam id qui incididunt laborum.]]></description>
- <link>http://example.com/test/1540941540</link>
- <guid isPermaLink="true">http://example.com/test/1540941540</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:19:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:18:00+00:00]]></title>
- <description><![CDATA[Velit proident aliquip aliquip anim mollit voluptate laboris voluptate et occaecat occaecat laboris ea nulla.]]></description>
- <link>http://example.com/test/1540941480</link>
- <guid isPermaLink="true">http://example.com/test/1540941480</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:18:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:17:00+00:00]]></title>
- <description><![CDATA[Do in quis mollit consequat id in minim laborum sint exercitation laborum elit officia.]]></description>
- <link>http://example.com/test/1540941420</link>
- <guid isPermaLink="true">http://example.com/test/1540941420</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:17:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:16:00+00:00]]></title>
- <description><![CDATA[Irure id sint ullamco Lorem magna consectetur officia adipisicing duis incididunt.]]></description>
- <link>http://example.com/test/1540941360</link>
- <guid isPermaLink="true">http://example.com/test/1540941360</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:16:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:15:00+00:00]]></title>
- <description><![CDATA[Sunt anim excepteur esse nisi commodo culpa laborum exercitation ad anim ex elit.]]></description>
- <link>http://example.com/test/1540941300</link>
- <guid isPermaLink="true">http://example.com/test/1540941300</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:15:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:14:00+00:00]]></title>
- <description><![CDATA[Excepteur aliquip fugiat ex labore nisi.]]></description>
- <link>http://example.com/test/1540941240</link>
- <guid isPermaLink="true">http://example.com/test/1540941240</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:14:00 GMT</pubDate>
- </entry>
- <entry>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:13:00+00:00]]></title>
- <description><![CDATA[Id proident adipisicing proident pariatur aute pariatur pariatur dolor dolor in voluptate dolor.]]></description>
- <link>http://example.com/test/1540941180</link>
- <guid isPermaLink="true">http://example.com/test/1540941180</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:13:00 GMT</pubDate>
- </entry>
-</feed> \ No newline at end of file
diff --git a/vendor/github.com/gorilla/feeds/test.rss b/vendor/github.com/gorilla/feeds/test.rss
deleted file mode 100644
index 8d912aba5..000000000
--- a/vendor/github.com/gorilla/feeds/test.rss
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<rss xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:content="http://purl.org/rss/1.0/modules/content/"
- xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
- <channel>
- <title><![CDATA[Lorem ipsum feed for an interval of 1 minutes]]></title>
- <description><![CDATA[This is a constantly updating lorem ipsum feed]]></description>
- <link>http://example.com/</link>
- <generator>RSS for Node</generator>
- <lastBuildDate>Tue, 30 Oct 2018 23:22:37 GMT</lastBuildDate>
- <author><![CDATA[John Smith]]></author>
- <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
- <copyright><![CDATA[Michael Bertolacci, licensed under a Creative Commons Attribution 3.0 Unported License.]]></copyright>
- <ttl>60</ttl>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:22:00+00:00]]></title>
- <description><![CDATA[Exercitation ut Lorem sint proident.]]></description>
- <link>http://example.com/test/1540941720</link>
- <guid isPermaLink="true">http://example.com/test/1540941720</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:21:00+00:00]]></title>
- <description><![CDATA[Ea est do quis fugiat exercitation.]]></description>
- <link>http://example.com/test/1540941660</link>
- <guid isPermaLink="true">http://example.com/test/1540941660</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:21:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:20:00+00:00]]></title>
- <description><![CDATA[Ipsum velit cillum ad laborum sit nulla exercitation consequat sint veniam culpa veniam voluptate incididunt.]]></description>
- <link>http://example.com/test/1540941600</link>
- <guid isPermaLink="true">http://example.com/test/1540941600</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:20:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:19:00+00:00]]></title>
- <description><![CDATA[Ullamco pariatur aliqua consequat ea veniam id qui incididunt laborum.]]></description>
- <link>http://example.com/test/1540941540</link>
- <guid isPermaLink="true">http://example.com/test/1540941540</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:19:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:18:00+00:00]]></title>
- <description><![CDATA[Velit proident aliquip aliquip anim mollit voluptate laboris voluptate et occaecat occaecat laboris ea nulla.]]></description>
- <link>http://example.com/test/1540941480</link>
- <guid isPermaLink="true">http://example.com/test/1540941480</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:18:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:17:00+00:00]]></title>
- <description><![CDATA[Do in quis mollit consequat id in minim laborum sint exercitation laborum elit officia.]]></description>
- <link>http://example.com/test/1540941420</link>
- <guid isPermaLink="true">http://example.com/test/1540941420</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:17:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:16:00+00:00]]></title>
- <description><![CDATA[Irure id sint ullamco Lorem magna consectetur officia adipisicing duis incididunt.]]></description>
- <link>http://example.com/test/1540941360</link>
- <guid isPermaLink="true">http://example.com/test/1540941360</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:16:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:15:00+00:00]]></title>
- <description><![CDATA[Sunt anim excepteur esse nisi commodo culpa laborum exercitation ad anim ex elit.]]></description>
- <link>http://example.com/test/1540941300</link>
- <guid isPermaLink="true">http://example.com/test/1540941300</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:15:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:14:00+00:00]]></title>
- <description><![CDATA[Excepteur aliquip fugiat ex labore nisi.]]></description>
- <link>http://example.com/test/1540941240</link>
- <guid isPermaLink="true">http://example.com/test/1540941240</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:14:00 GMT</pubDate>
- </item>
- <item>
- <title><![CDATA[Lorem ipsum 2018-10-30T23:13:00+00:00]]></title>
- <description><![CDATA[Id proident adipisicing proident pariatur aute pariatur pariatur dolor dolor in voluptate dolor.]]></description>
- <link>http://example.com/test/1540941180</link>
- <guid isPermaLink="true">http://example.com/test/1540941180</guid>
- <dc:creator><![CDATA[John Smith]]></dc:creator>
- <pubDate>Tue, 30 Oct 2018 23:13:00 GMT</pubDate>
- </item>
- </channel>
-</rss> \ No newline at end of file
diff --git a/vendor/github.com/gorilla/feeds/to-implement.md b/vendor/github.com/gorilla/feeds/to-implement.md
deleted file mode 100644
index 45fd1e75e..000000000
--- a/vendor/github.com/gorilla/feeds/to-implement.md
+++ /dev/null
@@ -1,20 +0,0 @@
-[Full iTunes list](https://help.apple.com/itc/podcasts_connect/#/itcb54353390)
-
-[Example of ideal iTunes RSS feed](https://help.apple.com/itc/podcasts_connect/#/itcbaf351599)
-
-```
-<itunes:author>
-<itunes:block>
-<itunes:catergory>
-<itunes:image>
-<itunes:duration>
-<itunes:explicit>
-<itunes:isClosedCaptioned>
-<itunes:order>
-<itunes:complete>
-<itunes:new-feed-url>
-<itunes:owner>
-<itunes:subtitle>
-<itunes:summary>
-<language>
-``` \ No newline at end of file
diff --git a/vendor/github.com/gorilla/feeds/uuid.go b/vendor/github.com/gorilla/feeds/uuid.go
deleted file mode 100644
index 51bbafe13..000000000
--- a/vendor/github.com/gorilla/feeds/uuid.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package feeds
-
-// relevant bits from https://github.com/abneptis/GoUUID/blob/master/uuid.go
-
-import (
- "crypto/rand"
- "fmt"
-)
-
-type UUID [16]byte
-
-// create a new uuid v4
-func NewUUID() *UUID {
- u := &UUID{}
- _, err := rand.Read(u[:16])
- if err != nil {
- panic(err)
- }
-
- u[8] = (u[8] | 0x80) & 0xBf
- u[6] = (u[6] | 0x40) & 0x4f
- return u
-}
-
-func (u *UUID) String() string {
- return fmt.Sprintf("%x-%x-%x-%x-%x", u[:4], u[4:6], u[6:8], u[8:10], u[10:])
-}
diff --git a/vendor/github.com/gorilla/handlers/.editorconfig b/vendor/github.com/gorilla/handlers/.editorconfig
deleted file mode 100644
index c6b74c3e0..000000000
--- a/vendor/github.com/gorilla/handlers/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-; https://editorconfig.org/
-
-root = true
-
-[*]
-insert_final_newline = true
-charset = utf-8
-trim_trailing_whitespace = true
-indent_style = space
-indent_size = 2
-
-[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
-indent_style = tab
-indent_size = 4
-
-[*.md]
-indent_size = 4
-trim_trailing_whitespace = false
-
-eclint_indent_style = unset \ No newline at end of file
diff --git a/vendor/github.com/gorilla/handlers/.gitignore b/vendor/github.com/gorilla/handlers/.gitignore
deleted file mode 100644
index 577a89e81..000000000
--- a/vendor/github.com/gorilla/handlers/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Output of the go test coverage tool
-coverage.coverprofile
diff --git a/vendor/github.com/gorilla/handlers/LICENSE b/vendor/github.com/gorilla/handlers/LICENSE
deleted file mode 100644
index bb9d80bc9..000000000
--- a/vendor/github.com/gorilla/handlers/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2023 The Gorilla Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gorilla/handlers/Makefile b/vendor/github.com/gorilla/handlers/Makefile
deleted file mode 100644
index 003b784f7..000000000
--- a/vendor/github.com/gorilla/handlers/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
-GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
-
-GO_SEC=$(shell which gosec 2> /dev/null || echo '')
-GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
-
-GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
-GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
-
-.PHONY: verify
-verify: sec govulncheck lint test
-
-.PHONY: lint
-lint:
- $(if $(GO_LINT), ,go install $(GO_LINT_URI))
- @echo "##### Running golangci-lint #####"
- golangci-lint run -v
-
-.PHONY: sec
-sec:
- $(if $(GO_SEC), ,go install $(GO_SEC_URI))
- @echo "##### Running gosec #####"
- gosec ./...
-
-.PHONY: govulncheck
-govulncheck:
- $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
- @echo "##### Running govulncheck #####"
- govulncheck ./...
-
-.PHONY: test
-test:
- @echo "##### Running tests #####"
- go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
diff --git a/vendor/github.com/gorilla/handlers/README.md b/vendor/github.com/gorilla/handlers/README.md
deleted file mode 100644
index 02555b264..000000000
--- a/vendor/github.com/gorilla/handlers/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# gorilla/handlers
-
-![Testing](https://github.com/gorilla/handlers/actions/workflows/test.yml/badge.svg)
-[![Codecov](https://codecov.io/github/gorilla/handlers/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/handlers)
-[![GoDoc](https://godoc.org/github.com/gorilla/handlers?status.svg)](https://godoc.org/github.com/gorilla/handlers)
-[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/handlers/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/handlers?badge)
-
-Package handlers is a collection of handlers (aka "HTTP middleware") for use
-with Go's `net/http` package (or any framework supporting `http.Handler`), including:
-
-* [**LoggingHandler**](https://godoc.org/github.com/gorilla/handlers#LoggingHandler) for logging HTTP requests in the Apache [Common Log
- Format](http://httpd.apache.org/docs/2.2/logs.html#common).
-* [**CombinedLoggingHandler**](https://godoc.org/github.com/gorilla/handlers#CombinedLoggingHandler) for logging HTTP requests in the Apache [Combined Log
- Format](http://httpd.apache.org/docs/2.2/logs.html#combined) commonly used by
- both Apache and nginx.
-* [**CompressHandler**](https://godoc.org/github.com/gorilla/handlers#CompressHandler) for gzipping responses.
-* [**ContentTypeHandler**](https://godoc.org/github.com/gorilla/handlers#ContentTypeHandler) for validating requests against a list of accepted
- content types.
-* [**MethodHandler**](https://godoc.org/github.com/gorilla/handlers#MethodHandler) for matching HTTP methods against handlers in a
- `map[string]http.Handler`
-* [**ProxyHeaders**](https://godoc.org/github.com/gorilla/handlers#ProxyHeaders) for populating `r.RemoteAddr` and `r.URL.Scheme` based on the
- `X-Forwarded-For`, `X-Real-IP`, `X-Forwarded-Proto` and RFC7239 `Forwarded`
- headers when running a Go server behind a HTTP reverse proxy.
-* [**CanonicalHost**](https://godoc.org/github.com/gorilla/handlers#CanonicalHost) for re-directing to the preferred host when handling multiple
- domains (i.e. multiple CNAME aliases).
-* [**RecoveryHandler**](https://godoc.org/github.com/gorilla/handlers#RecoveryHandler) for recovering from unexpected panics.
-
-Other handlers are documented [on the Gorilla
-website](https://www.gorillatoolkit.org/pkg/handlers).
-
-## Example
-
-A simple example using `handlers.LoggingHandler` and `handlers.CompressHandler`:
-
-```go
-import (
- "net/http"
- "github.com/gorilla/handlers"
-)
-
-func main() {
- r := http.NewServeMux()
-
- // Only log requests to our admin dashboard to stdout
- r.Handle("/admin", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(ShowAdminDashboard)))
- r.HandleFunc("/", ShowIndex)
-
- // Wrap our server with our gzip handler to gzip compress all responses.
- http.ListenAndServe(":8000", handlers.CompressHandler(r))
-}
-```
-
-## License
-
-BSD licensed. See the included LICENSE file for details.
-
diff --git a/vendor/github.com/gorilla/handlers/canonical.go b/vendor/github.com/gorilla/handlers/canonical.go
deleted file mode 100644
index 7121f5307..000000000
--- a/vendor/github.com/gorilla/handlers/canonical.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "net/url"
- "strings"
-)
-
-type canonical struct {
- h http.Handler
- domain string
- code int
-}
-
-// CanonicalHost is HTTP middleware that re-directs requests to the canonical
-// domain. It accepts a domain and a status code (e.g. 301 or 302) and
-// re-directs clients to this domain. The existing request path is maintained.
-//
-// Note: If the provided domain is considered invalid by url.Parse or otherwise
-// returns an empty scheme or host, clients are not re-directed.
-//
-// Example:
-//
-// r := mux.NewRouter()
-// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
-// r.HandleFunc("/route", YourHandler)
-//
-// log.Fatal(http.ListenAndServe(":7000", canonical(r)))
-func CanonicalHost(domain string, code int) func(h http.Handler) http.Handler {
- fn := func(h http.Handler) http.Handler {
- return canonical{h, domain, code}
- }
-
- return fn
-}
-
-func (c canonical) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- dest, err := url.Parse(c.domain)
- if err != nil {
- // Call the next handler if the provided domain fails to parse.
- c.h.ServeHTTP(w, r)
- return
- }
-
- if dest.Scheme == "" || dest.Host == "" {
- // Call the next handler if the scheme or host are empty.
- // Note that url.Parse won't fail on in this case.
- c.h.ServeHTTP(w, r)
- return
- }
-
- if !strings.EqualFold(cleanHost(r.Host), dest.Host) {
- // Re-build the destination URL
- dest := dest.Scheme + "://" + dest.Host + r.URL.Path
- if r.URL.RawQuery != "" {
- dest += "?" + r.URL.RawQuery
- }
- http.Redirect(w, r, dest, c.code)
- return
- }
-
- c.h.ServeHTTP(w, r)
-}
-
-// cleanHost cleans invalid Host headers by stripping anything after '/' or ' '.
-// This is backported from Go 1.5 (in response to issue #11206) and attempts to
-// mitigate malformed Host headers that do not match the format in RFC7230.
-func cleanHost(in string) string {
- if i := strings.IndexAny(in, " /"); i != -1 {
- return in[:i]
- }
- return in
-}
diff --git a/vendor/github.com/gorilla/handlers/compress.go b/vendor/github.com/gorilla/handlers/compress.go
deleted file mode 100644
index d6f589503..000000000
--- a/vendor/github.com/gorilla/handlers/compress.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "compress/flate"
- "compress/gzip"
- "io"
- "net/http"
- "strings"
-
- "github.com/felixge/httpsnoop"
-)
-
-const acceptEncoding string = "Accept-Encoding"
-
-type compressResponseWriter struct {
- compressor io.Writer
- w http.ResponseWriter
-}
-
-func (cw *compressResponseWriter) WriteHeader(c int) {
- cw.w.Header().Del("Content-Length")
- cw.w.WriteHeader(c)
-}
-
-func (cw *compressResponseWriter) Write(b []byte) (int, error) {
- h := cw.w.Header()
- if h.Get("Content-Type") == "" {
- h.Set("Content-Type", http.DetectContentType(b))
- }
- h.Del("Content-Length")
-
- return cw.compressor.Write(b)
-}
-
-func (cw *compressResponseWriter) ReadFrom(r io.Reader) (int64, error) {
- return io.Copy(cw.compressor, r)
-}
-
-type flusher interface {
- Flush() error
-}
-
-func (cw *compressResponseWriter) Flush() {
- // Flush compressed data if compressor supports it.
- if f, ok := cw.compressor.(flusher); ok {
- _ = f.Flush()
- }
- // Flush HTTP response.
- if f, ok := cw.w.(http.Flusher); ok {
- f.Flush()
- }
-}
-
-// CompressHandler gzip compresses HTTP responses for clients that support it
-// via the 'Accept-Encoding' header.
-//
-// Compressing TLS traffic may leak the page contents to an attacker if the
-// page contains user input: http://security.stackexchange.com/a/102015/12208
-func CompressHandler(h http.Handler) http.Handler {
- return CompressHandlerLevel(h, gzip.DefaultCompression)
-}
-
-// CompressHandlerLevel gzip compresses HTTP responses with specified compression level
-// for clients that support it via the 'Accept-Encoding' header.
-//
-// The compression level should be gzip.DefaultCompression, gzip.NoCompression,
-// or any integer value between gzip.BestSpeed and gzip.BestCompression inclusive.
-// gzip.DefaultCompression is used in case of invalid compression level.
-func CompressHandlerLevel(h http.Handler, level int) http.Handler {
- if level < gzip.DefaultCompression || level > gzip.BestCompression {
- level = gzip.DefaultCompression
- }
-
- const (
- gzipEncoding = "gzip"
- flateEncoding = "deflate"
- )
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- // detect what encoding to use
- var encoding string
- for _, curEnc := range strings.Split(r.Header.Get(acceptEncoding), ",") {
- curEnc = strings.TrimSpace(curEnc)
- if curEnc == gzipEncoding || curEnc == flateEncoding {
- encoding = curEnc
- break
- }
- }
-
- // always add Accept-Encoding to Vary to prevent intermediate caches corruption
- w.Header().Add("Vary", acceptEncoding)
-
- // if we weren't able to identify an encoding we're familiar with, pass on the
- // request to the handler and return
- if encoding == "" {
- h.ServeHTTP(w, r)
- return
- }
-
- if r.Header.Get("Upgrade") != "" {
- h.ServeHTTP(w, r)
- return
- }
-
- // wrap the ResponseWriter with the writer for the chosen encoding
- var encWriter io.WriteCloser
- if encoding == gzipEncoding {
- encWriter, _ = gzip.NewWriterLevel(w, level)
- } else if encoding == flateEncoding {
- encWriter, _ = flate.NewWriter(w, level)
- }
- defer encWriter.Close()
-
- w.Header().Set("Content-Encoding", encoding)
- r.Header.Del(acceptEncoding)
-
- cw := &compressResponseWriter{
- w: w,
- compressor: encWriter,
- }
-
- w = httpsnoop.Wrap(w, httpsnoop.Hooks{
- Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {
- return cw.Write
- },
- WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
- return cw.WriteHeader
- },
- Flush: func(httpsnoop.FlushFunc) httpsnoop.FlushFunc {
- return cw.Flush
- },
- ReadFrom: func(rff httpsnoop.ReadFromFunc) httpsnoop.ReadFromFunc {
- return cw.ReadFrom
- },
- })
-
- h.ServeHTTP(w, r)
- })
-}
diff --git a/vendor/github.com/gorilla/handlers/cors.go b/vendor/github.com/gorilla/handlers/cors.go
deleted file mode 100644
index 8af9c096e..000000000
--- a/vendor/github.com/gorilla/handlers/cors.go
+++ /dev/null
@@ -1,352 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "strconv"
- "strings"
-)
-
-// CORSOption represents a functional option for configuring the CORS middleware.
-type CORSOption func(*cors) error
-
-type cors struct {
- h http.Handler
- allowedHeaders []string
- allowedMethods []string
- allowedOrigins []string
- allowedOriginValidator OriginValidator
- exposedHeaders []string
- maxAge int
- ignoreOptions bool
- allowCredentials bool
- optionStatusCode int
-}
-
-// OriginValidator takes an origin string and returns whether or not that origin is allowed.
-type OriginValidator func(string) bool
-
-var (
- defaultCorsOptionStatusCode = http.StatusOK
- defaultCorsMethods = []string{http.MethodGet, http.MethodHead, http.MethodPost}
- defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"}
- // (WebKit/Safari v9 sends the Origin header by default in AJAX requests).
-)
-
-const (
- corsOptionMethod string = http.MethodOptions
- corsAllowOriginHeader string = "Access-Control-Allow-Origin"
- corsExposeHeadersHeader string = "Access-Control-Expose-Headers"
- corsMaxAgeHeader string = "Access-Control-Max-Age"
- corsAllowMethodsHeader string = "Access-Control-Allow-Methods"
- corsAllowHeadersHeader string = "Access-Control-Allow-Headers"
- corsAllowCredentialsHeader string = "Access-Control-Allow-Credentials"
- corsRequestMethodHeader string = "Access-Control-Request-Method"
- corsRequestHeadersHeader string = "Access-Control-Request-Headers"
- corsOriginHeader string = "Origin"
- corsVaryHeader string = "Vary"
- corsOriginMatchAll string = "*"
-)
-
-func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- origin := r.Header.Get(corsOriginHeader)
- if !ch.isOriginAllowed(origin) {
- if r.Method != corsOptionMethod || ch.ignoreOptions {
- ch.h.ServeHTTP(w, r)
- }
-
- return
- }
-
- if r.Method == corsOptionMethod {
- if ch.ignoreOptions {
- ch.h.ServeHTTP(w, r)
- return
- }
-
- if _, ok := r.Header[corsRequestMethodHeader]; !ok {
- w.WriteHeader(http.StatusBadRequest)
- return
- }
-
- method := r.Header.Get(corsRequestMethodHeader)
- if !ch.isMatch(method, ch.allowedMethods) {
- w.WriteHeader(http.StatusMethodNotAllowed)
- return
- }
-
- requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), ",")
- allowedHeaders := []string{}
- for _, v := range requestHeaders {
- canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if canonicalHeader == "" || ch.isMatch(canonicalHeader, defaultCorsHeaders) {
- continue
- }
-
- if !ch.isMatch(canonicalHeader, ch.allowedHeaders) {
- w.WriteHeader(http.StatusForbidden)
- return
- }
-
- allowedHeaders = append(allowedHeaders, canonicalHeader)
- }
-
- if len(allowedHeaders) > 0 {
- w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, ","))
- }
-
- if ch.maxAge > 0 {
- w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge))
- }
-
- if !ch.isMatch(method, defaultCorsMethods) {
- w.Header().Set(corsAllowMethodsHeader, method)
- }
- } else if len(ch.exposedHeaders) > 0 {
- w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
- }
-
- if ch.allowCredentials {
- w.Header().Set(corsAllowCredentialsHeader, "true")
- }
-
- if len(ch.allowedOrigins) > 1 {
- w.Header().Set(corsVaryHeader, corsOriginHeader)
- }
-
- returnOrigin := origin
- if ch.allowedOriginValidator == nil && len(ch.allowedOrigins) == 0 {
- returnOrigin = "*"
- } else {
- for _, o := range ch.allowedOrigins {
- // A configuration of * is different than explicitly setting an allowed
- // origin. Returning arbitrary origin headers in an access control allow
- // origin header is unsafe and is not required by any use case.
- if o == corsOriginMatchAll {
- returnOrigin = "*"
- break
- }
- }
- }
- w.Header().Set(corsAllowOriginHeader, returnOrigin)
-
- if r.Method == corsOptionMethod {
- w.WriteHeader(ch.optionStatusCode)
- return
- }
- ch.h.ServeHTTP(w, r)
-}
-
-// CORS provides Cross-Origin Resource Sharing middleware.
-// Example:
-//
-// import (
-// "net/http"
-//
-// "github.com/gorilla/handlers"
-// "github.com/gorilla/mux"
-// )
-//
-// func main() {
-// r := mux.NewRouter()
-// r.HandleFunc("/users", UserEndpoint)
-// r.HandleFunc("/projects", ProjectEndpoint)
-//
-// // Apply the CORS middleware to our top-level router, with the defaults.
-// http.ListenAndServe(":8000", handlers.CORS()(r))
-// }
-func CORS(opts ...CORSOption) func(http.Handler) http.Handler {
- return func(h http.Handler) http.Handler {
- ch := parseCORSOptions(opts...)
- ch.h = h
- return ch
- }
-}
-
-func parseCORSOptions(opts ...CORSOption) *cors {
- ch := &cors{
- allowedMethods: defaultCorsMethods,
- allowedHeaders: defaultCorsHeaders,
- allowedOrigins: []string{},
- optionStatusCode: defaultCorsOptionStatusCode,
- }
-
- for _, option := range opts {
- _ = option(ch) //TODO: @bharat-rajani, return error to caller if not nil?
- }
-
- return ch
-}
-
-//
-// Functional options for configuring CORS.
-//
-
-// AllowedHeaders adds the provided headers to the list of allowed headers in a
-// CORS request.
-// This is an append operation so the headers Accept, Accept-Language,
-// and Content-Language are always allowed.
-// Content-Type must be explicitly declared if accepting Content-Types other than
-// application/x-www-form-urlencoded, multipart/form-data, or text/plain.
-func AllowedHeaders(headers []string) CORSOption {
- return func(ch *cors) error {
- for _, v := range headers {
- normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if normalizedHeader == "" {
- continue
- }
-
- if !ch.isMatch(normalizedHeader, ch.allowedHeaders) {
- ch.allowedHeaders = append(ch.allowedHeaders, normalizedHeader)
- }
- }
-
- return nil
- }
-}
-
-// AllowedMethods can be used to explicitly allow methods in the
-// Access-Control-Allow-Methods header.
-// This is a replacement operation so you must also
-// pass GET, HEAD, and POST if you wish to support those methods.
-func AllowedMethods(methods []string) CORSOption {
- return func(ch *cors) error {
- ch.allowedMethods = []string{}
- for _, v := range methods {
- normalizedMethod := strings.ToUpper(strings.TrimSpace(v))
- if normalizedMethod == "" {
- continue
- }
-
- if !ch.isMatch(normalizedMethod, ch.allowedMethods) {
- ch.allowedMethods = append(ch.allowedMethods, normalizedMethod)
- }
- }
-
- return nil
- }
-}
-
-// AllowedOrigins sets the allowed origins for CORS requests, as used in the
-// 'Allow-Access-Control-Origin' HTTP header.
-// Note: Passing in a []string{"*"} will allow any domain.
-func AllowedOrigins(origins []string) CORSOption {
- return func(ch *cors) error {
- for _, v := range origins {
- if v == corsOriginMatchAll {
- ch.allowedOrigins = []string{corsOriginMatchAll}
- return nil
- }
- }
-
- ch.allowedOrigins = origins
- return nil
- }
-}
-
-// AllowedOriginValidator sets a function for evaluating allowed origins in CORS requests, represented by the
-// 'Allow-Access-Control-Origin' HTTP header.
-func AllowedOriginValidator(fn OriginValidator) CORSOption {
- return func(ch *cors) error {
- ch.allowedOriginValidator = fn
- return nil
- }
-}
-
-// OptionStatusCode sets a custom status code on the OPTIONS requests.
-// Default behaviour sets it to 200 to reflect best practices. This is option is not mandatory
-// and can be used if you need a custom status code (i.e 204).
-//
-// More informations on the spec:
-// https://fetch.spec.whatwg.org/#cors-preflight-fetch
-func OptionStatusCode(code int) CORSOption {
- return func(ch *cors) error {
- ch.optionStatusCode = code
- return nil
- }
-}
-
-// ExposedHeaders can be used to specify headers that are available
-// and will not be stripped out by the user-agent.
-func ExposedHeaders(headers []string) CORSOption {
- return func(ch *cors) error {
- ch.exposedHeaders = []string{}
- for _, v := range headers {
- normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
- if normalizedHeader == "" {
- continue
- }
-
- if !ch.isMatch(normalizedHeader, ch.exposedHeaders) {
- ch.exposedHeaders = append(ch.exposedHeaders, normalizedHeader)
- }
- }
-
- return nil
- }
-}
-
-// MaxAge determines the maximum age (in seconds) between preflight requests. A
-// maximum of 10 minutes is allowed. An age above this value will default to 10
-// minutes.
-func MaxAge(age int) CORSOption {
- return func(ch *cors) error {
- // Maximum of 10 minutes.
- if age > 600 {
- age = 600
- }
-
- ch.maxAge = age
- return nil
- }
-}
-
-// IgnoreOptions causes the CORS middleware to ignore OPTIONS requests, instead
-// passing them through to the next handler. This is useful when your application
-// or framework has a pre-existing mechanism for responding to OPTIONS requests.
-func IgnoreOptions() CORSOption {
- return func(ch *cors) error {
- ch.ignoreOptions = true
- return nil
- }
-}
-
-// AllowCredentials can be used to specify that the user agent may pass
-// authentication details along with the request.
-func AllowCredentials() CORSOption {
- return func(ch *cors) error {
- ch.allowCredentials = true
- return nil
- }
-}
-
-func (ch *cors) isOriginAllowed(origin string) bool {
- if origin == "" {
- return false
- }
-
- if ch.allowedOriginValidator != nil {
- return ch.allowedOriginValidator(origin)
- }
-
- if len(ch.allowedOrigins) == 0 {
- return true
- }
-
- for _, allowedOrigin := range ch.allowedOrigins {
- if allowedOrigin == origin || allowedOrigin == corsOriginMatchAll {
- return true
- }
- }
-
- return false
-}
-
-func (ch *cors) isMatch(needle string, haystack []string) bool {
- for _, v := range haystack {
- if v == needle {
- return true
- }
- }
-
- return false
-}
diff --git a/vendor/github.com/gorilla/handlers/doc.go b/vendor/github.com/gorilla/handlers/doc.go
deleted file mode 100644
index 944e5a8ae..000000000
--- a/vendor/github.com/gorilla/handlers/doc.go
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-Package handlers is a collection of handlers (aka "HTTP middleware") for use
-with Go's net/http package (or any framework supporting http.Handler).
-
-The package includes handlers for logging in standardised formats, compressing
-HTTP responses, validating content types and other useful tools for manipulating
-requests and responses.
-*/
-package handlers
diff --git a/vendor/github.com/gorilla/handlers/handlers.go b/vendor/github.com/gorilla/handlers/handlers.go
deleted file mode 100644
index 9b92fce33..000000000
--- a/vendor/github.com/gorilla/handlers/handlers.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "bufio"
- "fmt"
- "net"
- "net/http"
- "sort"
- "strings"
-)
-
-// MethodHandler is an http.Handler that dispatches to a handler whose key in the
-// MethodHandler's map matches the name of the HTTP request's method, eg: GET
-//
-// If the request's method is OPTIONS and OPTIONS is not a key in the map then
-// the handler responds with a status of 200 and sets the Allow header to a
-// comma-separated list of available methods.
-//
-// If the request's method doesn't match any of its keys the handler responds
-// with a status of HTTP 405 "Method Not Allowed" and sets the Allow header to a
-// comma-separated list of available methods.
-type MethodHandler map[string]http.Handler
-
-func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- if handler, ok := h[req.Method]; ok {
- handler.ServeHTTP(w, req)
- } else {
- allow := []string{}
- for k := range h {
- allow = append(allow, k)
- }
- sort.Strings(allow)
- w.Header().Set("Allow", strings.Join(allow, ", "))
- if req.Method == http.MethodOptions {
- w.WriteHeader(http.StatusOK)
- } else {
- http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
- }
- }
-}
-
-// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP
-// status code and body size.
-type responseLogger struct {
- w http.ResponseWriter
- status int
- size int
-}
-
-func (l *responseLogger) Write(b []byte) (int, error) {
- size, err := l.w.Write(b)
- l.size += size
- return size, err
-}
-
-func (l *responseLogger) WriteHeader(s int) {
- l.w.WriteHeader(s)
- l.status = s
-}
-
-func (l *responseLogger) Status() int {
- return l.status
-}
-
-func (l *responseLogger) Size() int {
- return l.size
-}
-
-func (l *responseLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- conn, rw, err := l.w.(http.Hijacker).Hijack()
- if err == nil && l.status == 0 {
- // The status will be StatusSwitchingProtocols if there was no error and
- // WriteHeader has not been called yet
- l.status = http.StatusSwitchingProtocols
- }
- return conn, rw, err
-}
-
-// isContentType validates the Content-Type header matches the supplied
-// contentType. That is, its type and subtype match.
-func isContentType(h http.Header, contentType string) bool {
- ct := h.Get("Content-Type")
- if i := strings.IndexRune(ct, ';'); i != -1 {
- ct = ct[0:i]
- }
- return ct == contentType
-}
-
-// ContentTypeHandler wraps and returns a http.Handler, validating the request
-// content type is compatible with the contentTypes list. It writes a HTTP 415
-// error if that fails.
-//
-// Only PUT, POST, and PATCH requests are considered.
-func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if !(r.Method == http.MethodPut || r.Method == http.MethodPost || r.Method == http.MethodPatch) {
- h.ServeHTTP(w, r)
- return
- }
-
- for _, ct := range contentTypes {
- if isContentType(r.Header, ct) {
- h.ServeHTTP(w, r)
- return
- }
- }
- http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q",
- r.Header.Get("Content-Type"),
- contentTypes),
- http.StatusUnsupportedMediaType)
- })
-}
-
-const (
- // HTTPMethodOverrideHeader is a commonly used
- // http header to override a request method.
- HTTPMethodOverrideHeader = "X-HTTP-Method-Override"
- // HTTPMethodOverrideFormKey is a commonly used
- // HTML form key to override a request method.
- HTTPMethodOverrideFormKey = "_method"
-)
-
-// HTTPMethodOverrideHandler wraps and returns a http.Handler which checks for
-// the X-HTTP-Method-Override header or the _method form key, and overrides (if
-// valid) request.Method with its value.
-//
-// This is especially useful for HTTP clients that don't support many http verbs.
-// It isn't secure to override e.g a GET to a POST, so only POST requests are
-// considered. Likewise, the override method can only be a "write" method: PUT,
-// PATCH or DELETE.
-//
-// Form method takes precedence over header method.
-func HTTPMethodOverrideHandler(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method == http.MethodPost {
- om := r.FormValue(HTTPMethodOverrideFormKey)
- if om == "" {
- om = r.Header.Get(HTTPMethodOverrideHeader)
- }
- if om == http.MethodPut || om == http.MethodPatch || om == http.MethodDelete {
- r.Method = om
- }
- }
- h.ServeHTTP(w, r)
- })
-}
diff --git a/vendor/github.com/gorilla/handlers/logging.go b/vendor/github.com/gorilla/handlers/logging.go
deleted file mode 100644
index 2badb6fbf..000000000
--- a/vendor/github.com/gorilla/handlers/logging.go
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2013 The Gorilla Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package handlers
-
-import (
- "io"
- "net"
- "net/http"
- "net/url"
- "strconv"
- "time"
- "unicode/utf8"
-
- "github.com/felixge/httpsnoop"
-)
-
-// Logging
-
-// LogFormatterParams is the structure any formatter will be handed when time to log comes.
-type LogFormatterParams struct {
- Request *http.Request
- URL url.URL
- TimeStamp time.Time
- StatusCode int
- Size int
-}
-
-// LogFormatter gives the signature of the formatter function passed to CustomLoggingHandler.
-type LogFormatter func(writer io.Writer, params LogFormatterParams)
-
-// loggingHandler is the http.Handler implementation for LoggingHandlerTo and its
-// friends
-
-type loggingHandler struct {
- writer io.Writer
- handler http.Handler
- formatter LogFormatter
-}
-
-func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- t := time.Now()
- logger, w := makeLogger(w)
- url := *req.URL
-
- h.handler.ServeHTTP(w, req)
- if req.MultipartForm != nil {
- err := req.MultipartForm.RemoveAll()
- if err != nil {
- return
- }
- }
-
- params := LogFormatterParams{
- Request: req,
- URL: url,
- TimeStamp: t,
- StatusCode: logger.Status(),
- Size: logger.Size(),
- }
-
- h.formatter(h.writer, params)
-}
-
-func makeLogger(w http.ResponseWriter) (*responseLogger, http.ResponseWriter) {
- logger := &responseLogger{w: w, status: http.StatusOK}
- return logger, httpsnoop.Wrap(w, httpsnoop.Hooks{
- Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {
- return logger.Write
- },
- WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
- return logger.WriteHeader
- },
- })
-}
-
-const lowerhex = "0123456789abcdef"
-
-func appendQuoted(buf []byte, s string) []byte {
- var runeTmp [utf8.UTFMax]byte
- for width := 0; len(s) > 0; s = s[width:] { //nolint: wastedassign //TODO: why width starts from 0and reassigned as 1
- r := rune(s[0])
- width = 1
- if r >= utf8.RuneSelf {
- r, width = utf8.DecodeRuneInString(s)
- }
- if width == 1 && r == utf8.RuneError {
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[0]>>4])
- buf = append(buf, lowerhex[s[0]&0xF])
- continue
- }
- if r == rune('"') || r == '\\' { // always backslashed
- buf = append(buf, '\\')
- buf = append(buf, byte(r))
- continue
- }
- if strconv.IsPrint(r) {
- n := utf8.EncodeRune(runeTmp[:], r)
- buf = append(buf, runeTmp[:n]...)
- continue
- }
- switch r {
- case '\a':
- buf = append(buf, `\a`...)
- case '\b':
- buf = append(buf, `\b`...)
- case '\f':
- buf = append(buf, `\f`...)
- case '\n':
- buf = append(buf, `\n`...)
- case '\r':
- buf = append(buf, `\r`...)
- case '\t':
- buf = append(buf, `\t`...)
- case '\v':
- buf = append(buf, `\v`...)
- default:
- switch {
- case r < ' ':
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[0]>>4])
- buf = append(buf, lowerhex[s[0]&0xF])
- case r > utf8.MaxRune:
- r = 0xFFFD
- fallthrough
- case r < 0x10000:
- buf = append(buf, `\u`...)
- for s := 12; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
- default:
- buf = append(buf, `\U`...)
- for s := 28; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
- }
- }
- }
- return buf
-}
-
-// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte {
- username := "-"
- if url.User != nil {
- if name := url.User.Username(); name != "" {
- username = name
- }
- }
-
- host, _, err := net.SplitHostPort(req.RemoteAddr)
- if err != nil {
- host = req.RemoteAddr
- }
-
- uri := req.RequestURI
-
- // Requests using the CONNECT method over HTTP/2.0 must use
- // the authority field (aka r.Host) to identify the target.
- // Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT
- if req.ProtoMajor == 2 && req.Method == "CONNECT" {
- uri = req.Host
- }
- if uri == "" {
- uri = url.RequestURI()
- }
-
- buf := make([]byte, 0, 3*(len(host)+len(username)+len(req.Method)+len(uri)+len(req.Proto)+50)/2)
- buf = append(buf, host...)
- buf = append(buf, " - "...)
- buf = append(buf, username...)
- buf = append(buf, " ["...)
- buf = append(buf, ts.Format("02/Jan/2006:15:04:05 -0700")...)
- buf = append(buf, `] "`...)
- buf = append(buf, req.Method...)
- buf = append(buf, " "...)
- buf = appendQuoted(buf, uri)
- buf = append(buf, " "...)
- buf = append(buf, req.Proto...)
- buf = append(buf, `" `...)
- buf = append(buf, strconv.Itoa(status)...)
- buf = append(buf, " "...)
- buf = append(buf, strconv.Itoa(size)...)
- return buf
-}
-
-// writeLog writes a log entry for req to w in Apache Common Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func writeLog(writer io.Writer, params LogFormatterParams) {
- buf := buildCommonLogLine(params.Request, params.URL, params.TimeStamp, params.StatusCode, params.Size)
- buf = append(buf, '\n')
- _, _ = writer.Write(buf)
-}
-
-// writeCombinedLog writes a log entry for req to w in Apache Combined Log Format.
-// ts is the timestamp with which the entry should be logged.
-// status and size are used to provide the response HTTP status and size.
-func writeCombinedLog(writer io.Writer, params LogFormatterParams) {
- buf := buildCommonLogLine(params.Request, params.URL, params.TimeStamp, params.StatusCode, params.Size)
- buf = append(buf, ` "`...)
- buf = appendQuoted(buf, params.Request.Referer())
- buf = append(buf, `" "`...)
- buf = appendQuoted(buf, params.Request.UserAgent())
- buf = append(buf, '"', '\n')
- _, _ = writer.Write(buf)
-}
-
-// CombinedLoggingHandler return a http.Handler that wraps h and logs requests to out in
-// Apache Combined Log Format.
-//
-// See http://httpd.apache.org/docs/2.2/logs.html#combined for a description of this format.
-//
-// LoggingHandler always sets the ident field of the log to -.
-func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
- return loggingHandler{out, h, writeCombinedLog}
-}
-
-// LoggingHandler return a http.Handler that wraps h and logs requests to out in
-// Apache Common Log Format (CLF).
-//
-// See http://httpd.apache.org/docs/2.2/logs.html#common for a description of this format.
-//
-// LoggingHandler always sets the ident field of the log to -
-//
-// Example:
-//
-// r := mux.NewRouter()
-// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-// w.Write([]byte("This is a catch-all route"))
-// })
-// loggedRouter := handlers.LoggingHandler(os.Stdout, r)
-// http.ListenAndServe(":1123", loggedRouter)
-func LoggingHandler(out io.Writer, h http.Handler) http.Handler {
- return loggingHandler{out, h, writeLog}
-}
-
-// CustomLoggingHandler provides a way to supply a custom log formatter
-// while taking advantage of the mechanisms in this package.
-func CustomLoggingHandler(out io.Writer, h http.Handler, f LogFormatter) http.Handler {
- return loggingHandler{out, h, f}
-}
diff --git a/vendor/github.com/gorilla/handlers/proxy_headers.go b/vendor/github.com/gorilla/handlers/proxy_headers.go
deleted file mode 100644
index 281d753e9..000000000
--- a/vendor/github.com/gorilla/handlers/proxy_headers.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "regexp"
- "strings"
-)
-
-var (
- // De-facto standard header keys.
- xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
- xForwardedHost = http.CanonicalHeaderKey("X-Forwarded-Host")
- xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Proto")
- xForwardedScheme = http.CanonicalHeaderKey("X-Forwarded-Scheme")
- xRealIP = http.CanonicalHeaderKey("X-Real-IP")
-)
-
-var (
- // RFC7239 defines a new "Forwarded: " header designed to replace the
- // existing use of X-Forwarded-* headers.
- // e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43.
- forwarded = http.CanonicalHeaderKey("Forwarded")
- // Allows for a sub-match of the first value after 'for=' to the next
- // comma, semi-colon or space. The match is case-insensitive.
- forRegex = regexp.MustCompile(`(?i)(?:for=)([^(;|,| )]+)`)
- // Allows for a sub-match for the first instance of scheme (http|https)
- // prefixed by 'proto='. The match is case-insensitive.
- protoRegex = regexp.MustCompile(`(?i)(?:proto=)(https|http)`)
-)
-
-// ProxyHeaders inspects common reverse proxy headers and sets the corresponding
-// fields in the HTTP request struct. These are X-Forwarded-For and X-Real-IP
-// for the remote (client) IP address, X-Forwarded-Proto or X-Forwarded-Scheme
-// for the scheme (http|https), X-Forwarded-Host for the host and the RFC7239
-// Forwarded header, which may include both client IPs and schemes.
-//
-// NOTE: This middleware should only be used when behind a reverse
-// proxy like nginx, HAProxy or Apache. Reverse proxies that don't (or are
-// configured not to) strip these headers from client requests, or where these
-// headers are accepted "as is" from a remote client (e.g. when Go is not behind
-// a proxy), can manifest as a vulnerability if your application uses these
-// headers for validating the 'trustworthiness' of a request.
-func ProxyHeaders(h http.Handler) http.Handler {
- fn := func(w http.ResponseWriter, r *http.Request) {
- // Set the remote IP with the value passed from the proxy.
- if fwd := getIP(r); fwd != "" {
- r.RemoteAddr = fwd
- }
-
- // Set the scheme (proto) with the value passed from the proxy.
- if scheme := getScheme(r); scheme != "" {
- r.URL.Scheme = scheme
- }
- // Set the host with the value passed by the proxy
- if r.Header.Get(xForwardedHost) != "" {
- r.Host = r.Header.Get(xForwardedHost)
- }
- // Call the next handler in the chain.
- h.ServeHTTP(w, r)
- }
-
- return http.HandlerFunc(fn)
-}
-
-// getIP retrieves the IP from the X-Forwarded-For, X-Real-IP and RFC7239
-// Forwarded headers (in that order).
-func getIP(r *http.Request) string {
- var addr string
-
- switch {
- case r.Header.Get(xForwardedFor) != "":
- fwd := r.Header.Get(xForwardedFor)
- // Only grab the first (client) address. Note that '192.168.0.1,
- // 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
- // the first may represent forwarding proxies earlier in the chain.
- s := strings.Index(fwd, ", ")
- if s == -1 {
- s = len(fwd)
- }
- addr = fwd[:s]
- case r.Header.Get(xRealIP) != "":
- addr = r.Header.Get(xRealIP)
- case r.Header.Get(forwarded) != "":
- // match should contain at least two elements if the protocol was
- // specified in the Forwarded header. The first element will always be
- // the 'for=' capture, which we ignore. In the case of multiple IP
- // addresses (for=8.8.8.8, 8.8.4.4,172.16.1.20 is valid) we only
- // extract the first, which should be the client IP.
- if match := forRegex.FindStringSubmatch(r.Header.Get(forwarded)); len(match) > 1 {
- // IPv6 addresses in Forwarded headers are quoted-strings. We strip
- // these quotes.
- addr = strings.Trim(match[1], `"`)
- }
- }
-
- return addr
-}
-
-// getScheme retrieves the scheme from the X-Forwarded-Proto and RFC7239
-// Forwarded headers (in that order).
-func getScheme(r *http.Request) string {
- var scheme string
-
- // Retrieve the scheme from X-Forwarded-Proto.
- if proto := r.Header.Get(xForwardedProto); proto != "" {
- scheme = strings.ToLower(proto)
- } else if proto = r.Header.Get(xForwardedScheme); proto != "" {
- scheme = strings.ToLower(proto)
- } else if proto = r.Header.Get(forwarded); proto != "" {
- // match should contain at least two elements if the protocol was
- // specified in the Forwarded header. The first element will always be
- // the 'proto=' capture, which we ignore. In the case of multiple proto
- // parameters (invalid) we only extract the first.
- if match := protoRegex.FindStringSubmatch(proto); len(match) > 1 {
- scheme = strings.ToLower(match[1])
- }
- }
-
- return scheme
-}
diff --git a/vendor/github.com/gorilla/handlers/recovery.go b/vendor/github.com/gorilla/handlers/recovery.go
deleted file mode 100644
index 0d4f955ec..000000000
--- a/vendor/github.com/gorilla/handlers/recovery.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package handlers
-
-import (
- "log"
- "net/http"
- "runtime/debug"
-)
-
-// RecoveryHandlerLogger is an interface used by the recovering handler to print logs.
-type RecoveryHandlerLogger interface {
- Println(...interface{})
-}
-
-type recoveryHandler struct {
- handler http.Handler
- logger RecoveryHandlerLogger
- printStack bool
-}
-
-// RecoveryOption provides a functional approach to define
-// configuration for a handler; such as setting the logging
-// whether or not to print stack traces on panic.
-type RecoveryOption func(http.Handler)
-
-func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
- for _, option := range opts {
- option(h)
- }
-
- return h
-}
-
-// RecoveryHandler is HTTP middleware that recovers from a panic,
-// logs the panic, writes http.StatusInternalServerError, and
-// continues to the next handler.
-//
-// Example:
-//
-// r := mux.NewRouter()
-// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-// panic("Unexpected error!")
-// })
-//
-// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r))
-func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler {
- return func(h http.Handler) http.Handler {
- r := &recoveryHandler{handler: h}
- return parseRecoveryOptions(r, opts...)
- }
-}
-
-// RecoveryLogger is a functional option to override
-// the default logger.
-func RecoveryLogger(logger RecoveryHandlerLogger) RecoveryOption {
- return func(h http.Handler) {
- r := h.(*recoveryHandler) //nolint:errcheck //TODO:
- // @bharat-rajani should return type-assertion error but would break the API?
- r.logger = logger
- }
-}
-
-// PrintRecoveryStack is a functional option to enable
-// or disable printing stack traces on panic.
-func PrintRecoveryStack(shouldPrint bool) RecoveryOption {
- return func(h http.Handler) {
- r := h.(*recoveryHandler) //nolint:errcheck //TODO:
- // @bharat-rajani should return type-assertion error but would break the API?
- r.printStack = shouldPrint
- }
-}
-
-func (h recoveryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- defer func() {
- if err := recover(); err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- h.log(err)
- }
- }()
-
- h.handler.ServeHTTP(w, req)
-}
-
-func (h recoveryHandler) log(v ...interface{}) {
- if h.logger != nil {
- h.logger.Println(v...)
- } else {
- log.Println(v...)
- }
-
- if h.printStack {
- stack := string(debug.Stack())
- if h.logger != nil {
- h.logger.Println(stack)
- } else {
- log.Println(stack)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/securecookie/.editorconfig b/vendor/github.com/gorilla/securecookie/.editorconfig
deleted file mode 100644
index 2940ec92a..000000000
--- a/vendor/github.com/gorilla/securecookie/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-; https://editorconfig.org/
-
-root = true
-
-[*]
-insert_final_newline = true
-charset = utf-8
-trim_trailing_whitespace = true
-indent_style = space
-indent_size = 2
-
-[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
-indent_style = tab
-indent_size = 4
-
-[*.md]
-indent_size = 4
-trim_trailing_whitespace = false
-
-eclint_indent_style = unset
diff --git a/vendor/github.com/gorilla/securecookie/.gitignore b/vendor/github.com/gorilla/securecookie/.gitignore
deleted file mode 100644
index 84039fec6..000000000
--- a/vendor/github.com/gorilla/securecookie/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-coverage.coverprofile
diff --git a/vendor/github.com/gorilla/securecookie/LICENSE b/vendor/github.com/gorilla/securecookie/LICENSE
deleted file mode 100644
index bb9d80bc9..000000000
--- a/vendor/github.com/gorilla/securecookie/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2023 The Gorilla Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gorilla/securecookie/Makefile b/vendor/github.com/gorilla/securecookie/Makefile
deleted file mode 100644
index 2b9008a26..000000000
--- a/vendor/github.com/gorilla/securecookie/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
-GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
-
-GO_SEC=$(shell which gosec 2> /dev/null || echo '')
-GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
-
-GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
-GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
-
-.PHONY: golangci-lint
-golangci-lint:
- $(if $(GO_LINT), ,go install $(GO_LINT_URI))
- @echo "##### Running golangci-lint"
- golangci-lint run -v
-
-.PHONY: gosec
-gosec:
- $(if $(GO_SEC), ,go install $(GO_SEC_URI))
- @echo "##### Running gosec"
- gosec ./...
-
-.PHONY: govulncheck
-govulncheck:
- $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
- @echo "##### Running govulncheck"
- govulncheck ./...
-
-.PHONY: verify
-verify: golangci-lint gosec govulncheck
-
-.PHONY: test
-test:
- @echo "##### Running tests"
- go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
-
-.PHONY: fuzz
-fuzz:
- @echo "##### Running fuzz tests"
- go test -v -fuzz FuzzEncodeDecode -fuzztime 60s
diff --git a/vendor/github.com/gorilla/securecookie/README.md b/vendor/github.com/gorilla/securecookie/README.md
deleted file mode 100644
index c3b9815db..000000000
--- a/vendor/github.com/gorilla/securecookie/README.md
+++ /dev/null
@@ -1,144 +0,0 @@
-# gorilla/securecookie
-
-![testing](https://github.com/gorilla/securecookie/actions/workflows/test.yml/badge.svg)
-[![codecov](https://codecov.io/github/gorilla/securecookie/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/securecookie)
-[![godoc](https://godoc.org/github.com/gorilla/securecookie?status.svg)](https://godoc.org/github.com/gorilla/securecookie)
-[![sourcegraph](https://sourcegraph.com/github.com/gorilla/securecookie/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/securecookie?badge)
-
-![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5)
-
-securecookie encodes and decodes authenticated and optionally encrypted
-cookie values.
-
-Secure cookies can't be forged, because their values are validated using HMAC.
-When encrypted, the content is also inaccessible to malicious eyes. It is still
-recommended that sensitive data not be stored in cookies, and that HTTPS be used
-to prevent cookie [replay attacks](https://en.wikipedia.org/wiki/Replay_attack).
-
-## Examples
-
-To use it, first create a new SecureCookie instance:
-
-```go
-// Hash keys should be at least 32 bytes long
-var hashKey = []byte("very-secret")
-// Block keys should be 16 bytes (AES-128) or 32 bytes (AES-256) long.
-// Shorter keys may weaken the encryption used.
-var blockKey = []byte("a-lot-secret")
-var s = securecookie.New(hashKey, blockKey)
-```
-
-The hashKey is required, used to authenticate the cookie value using HMAC.
-It is recommended to use a key with 32 or 64 bytes.
-
-The blockKey is optional, used to encrypt the cookie value -- set it to nil
-to not use encryption. If set, the length must correspond to the block size
-of the encryption algorithm. For AES, used by default, valid lengths are
-16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
-
-Strong keys can be created using the convenience function
-`GenerateRandomKey()`. Note that keys created using `GenerateRandomKey()` are not
-automatically persisted. New keys will be created when the application is
-restarted, and previously issued cookies will not be able to be decoded.
-
-Once a SecureCookie instance is set, use it to encode a cookie value:
-
-```go
-func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
- value := map[string]string{
- "foo": "bar",
- }
- if encoded, err := s.Encode("cookie-name", value); err == nil {
- cookie := &http.Cookie{
- Name: "cookie-name",
- Value: encoded,
- Path: "/",
- Secure: true,
- HttpOnly: true,
- }
- http.SetCookie(w, cookie)
- }
-}
-```
-
-Later, use the same SecureCookie instance to decode and validate a cookie
-value:
-
-```go
-func ReadCookieHandler(w http.ResponseWriter, r *http.Request) {
- if cookie, err := r.Cookie("cookie-name"); err == nil {
- value := make(map[string]string)
- if err = s2.Decode("cookie-name", cookie.Value, &value); err == nil {
- fmt.Fprintf(w, "The value of foo is %q", value["foo"])
- }
- }
-}
-```
-
-We stored a map[string]string, but secure cookies can hold any value that
-can be encoded using `encoding/gob`. To store custom types, they must be
-registered first using gob.Register(). For basic types this is not needed;
-it works out of the box. An optional JSON encoder that uses `encoding/json` is
-available for types compatible with JSON.
-
-### Key Rotation
-Rotating keys is an important part of any security strategy. The `EncodeMulti` and
-`DecodeMulti` functions allow for multiple keys to be rotated in and out.
-For example, let's take a system that stores keys in a map:
-
-```go
-// keys stored in a map will not be persisted between restarts
-// a more persistent storage should be considered for production applications.
-var cookies = map[string]*securecookie.SecureCookie{
- "previous": securecookie.New(
- securecookie.GenerateRandomKey(64),
- securecookie.GenerateRandomKey(32),
- ),
- "current": securecookie.New(
- securecookie.GenerateRandomKey(64),
- securecookie.GenerateRandomKey(32),
- ),
-}
-```
-
-Using the current key to encode new cookies:
-```go
-func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
- value := map[string]string{
- "foo": "bar",
- }
- if encoded, err := securecookie.EncodeMulti("cookie-name", value, cookies["current"]); err == nil {
- cookie := &http.Cookie{
- Name: "cookie-name",
- Value: encoded,
- Path: "/",
- }
- http.SetCookie(w, cookie)
- }
-}
-```
-
-Later, decode cookies. Check against all valid keys:
-```go
-func ReadCookieHandler(w http.ResponseWriter, r *http.Request) {
- if cookie, err := r.Cookie("cookie-name"); err == nil {
- value := make(map[string]string)
- err = securecookie.DecodeMulti("cookie-name", cookie.Value, &value, cookies["current"], cookies["previous"])
- if err == nil {
- fmt.Fprintf(w, "The value of foo is %q", value["foo"])
- }
- }
-}
-```
-
-Rotate the keys. This strategy allows previously issued cookies to be valid until the next rotation:
-```go
-func Rotate(newCookie *securecookie.SecureCookie) {
- cookies["previous"] = cookies["current"]
- cookies["current"] = newCookie
-}
-```
-
-## License
-
-BSD licensed. See the LICENSE file for details.
diff --git a/vendor/github.com/gorilla/securecookie/doc.go b/vendor/github.com/gorilla/securecookie/doc.go
deleted file mode 100644
index ae89408d9..000000000
--- a/vendor/github.com/gorilla/securecookie/doc.go
+++ /dev/null
@@ -1,61 +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 securecookie encodes and decodes authenticated and optionally
-encrypted cookie values.
-
-Secure cookies can't be forged, because their values are validated using HMAC.
-When encrypted, the content is also inaccessible to malicious eyes.
-
-To use it, first create a new SecureCookie instance:
-
- var hashKey = []byte("very-secret")
- var blockKey = []byte("a-lot-secret")
- var s = securecookie.New(hashKey, blockKey)
-
-The hashKey is required, used to authenticate the cookie value using HMAC.
-It is recommended to use a key with 32 or 64 bytes.
-
-The blockKey is optional, used to encrypt the cookie value -- set it to nil
-to not use encryption. If set, the length must correspond to the block size
-of the encryption algorithm. For AES, used by default, valid lengths are
-16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
-
-Strong keys can be created using the convenience function GenerateRandomKey().
-
-Once a SecureCookie instance is set, use it to encode a cookie value:
-
- func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
- value := map[string]string{
- "foo": "bar",
- }
- if encoded, err := s.Encode("cookie-name", value); err == nil {
- cookie := &http.Cookie{
- Name: "cookie-name",
- Value: encoded,
- Path: "/",
- }
- http.SetCookie(w, cookie)
- }
- }
-
-Later, use the same SecureCookie instance to decode and validate a cookie
-value:
-
- func ReadCookieHandler(w http.ResponseWriter, r *http.Request) {
- if cookie, err := r.Cookie("cookie-name"); err == nil {
- value := make(map[string]string)
- if err = s2.Decode("cookie-name", cookie.Value, &value); err == nil {
- fmt.Fprintf(w, "The value of foo is %q", value["foo"])
- }
- }
- }
-
-We stored a map[string]string, but secure cookies can hold any value that
-can be encoded using encoding/gob. To store custom types, they must be
-registered first using gob.Register(). For basic types this is not needed;
-it works out of the box.
-*/
-package securecookie
diff --git a/vendor/github.com/gorilla/securecookie/securecookie.go b/vendor/github.com/gorilla/securecookie/securecookie.go
deleted file mode 100644
index 4d5ea860d..000000000
--- a/vendor/github.com/gorilla/securecookie/securecookie.go
+++ /dev/null
@@ -1,649 +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 securecookie
-
-import (
- "bytes"
- "crypto/aes"
- "crypto/cipher"
- "crypto/hmac"
- "crypto/rand"
- "crypto/sha256"
- "crypto/subtle"
- "encoding/base64"
- "encoding/gob"
- "encoding/json"
- "fmt"
- "hash"
- "io"
- "strconv"
- "strings"
- "time"
-)
-
-// Error is the interface of all errors returned by functions in this library.
-type Error interface {
- error
-
- // IsUsage returns true for errors indicating the client code probably
- // uses this library incorrectly. For example, the client may have
- // failed to provide a valid hash key, or may have failed to configure
- // the Serializer adequately for encoding value.
- IsUsage() bool
-
- // IsDecode returns true for errors indicating that a cookie could not
- // be decoded and validated. Since cookies are usually untrusted
- // user-provided input, errors of this type should be expected.
- // Usually, the proper action is simply to reject the request.
- IsDecode() bool
-
- // IsInternal returns true for unexpected errors occurring in the
- // securecookie implementation.
- IsInternal() bool
-
- // Cause, if it returns a non-nil value, indicates that this error was
- // propagated from some underlying library. If this method returns nil,
- // this error was raised directly by this library.
- //
- // Cause is provided principally for debugging/logging purposes; it is
- // rare that application logic should perform meaningfully different
- // logic based on Cause. See, for example, the caveats described on
- // (MultiError).Cause().
- Cause() error
-}
-
-// errorType is a bitmask giving the error type(s) of an cookieError value.
-type errorType int
-
-const (
- usageError = errorType(1 << iota)
- decodeError
- internalError
-)
-
-type cookieError struct {
- typ errorType
- msg string
- cause error
-}
-
-func (e cookieError) IsUsage() bool { return (e.typ & usageError) != 0 }
-func (e cookieError) IsDecode() bool { return (e.typ & decodeError) != 0 }
-func (e cookieError) IsInternal() bool { return (e.typ & internalError) != 0 }
-
-func (e cookieError) Cause() error { return e.cause }
-
-func (e cookieError) Error() string {
- parts := []string{"securecookie: "}
- if e.msg == "" {
- parts = append(parts, "error")
- } else {
- parts = append(parts, e.msg)
- }
- if c := e.Cause(); c != nil {
- parts = append(parts, " - caused by: ", c.Error())
- }
- return strings.Join(parts, "")
-}
-
-var (
- errGeneratingIV = cookieError{typ: internalError, msg: "failed to generate random iv"}
-
- errNoCodecs = cookieError{typ: usageError, msg: "no codecs provided"}
- errHashKeyNotSet = cookieError{typ: usageError, msg: "hash key is not set"}
- errBlockKeyNotSet = cookieError{typ: usageError, msg: "block key is not set"}
- errEncodedValueTooLong = cookieError{typ: usageError, msg: "the value is too long"}
-
- errValueToDecodeTooLong = cookieError{typ: decodeError, msg: "the value is too long"}
- errTimestampInvalid = cookieError{typ: decodeError, msg: "invalid timestamp"}
- errTimestampTooNew = cookieError{typ: decodeError, msg: "timestamp is too new"}
- errTimestampExpired = cookieError{typ: decodeError, msg: "expired timestamp"}
- errDecryptionFailed = cookieError{typ: decodeError, msg: "the value could not be decrypted"}
- errValueNotByte = cookieError{typ: decodeError, msg: "value not a []byte."}
- errValueNotBytePtr = cookieError{typ: decodeError, msg: "value not a pointer to []byte."}
-
- // ErrMacInvalid indicates that cookie decoding failed because the HMAC
- // could not be extracted and verified. Direct use of this error
- // variable is deprecated; it is public only for legacy compatibility,
- // and may be privatized in the future, as it is rarely useful to
- // distinguish between this error and other Error implementations.
- ErrMacInvalid = cookieError{typ: decodeError, msg: "the value is not valid"}
-)
-
-// Codec defines an interface to encode and decode cookie values.
-type Codec interface {
- Encode(name string, value interface{}) (string, error)
- Decode(name, value string, dst interface{}) error
-}
-
-// New returns a new SecureCookie.
-//
-// hashKey is required, used to authenticate values using HMAC. Create it using
-// GenerateRandomKey(). It is recommended to use a key with 32 or 64 bytes.
-//
-// blockKey is optional, used to encrypt values. Create it using
-// GenerateRandomKey(). The key length must correspond to the key size
-// of the encryption algorithm. For AES, used by default, valid lengths are
-// 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
-// The default encoder used for cookie serialization is encoding/gob.
-//
-// Note that keys created using GenerateRandomKey() are not automatically
-// persisted. New keys will be created when the application is restarted, and
-// previously issued cookies will not be able to be decoded.
-func New(hashKey, blockKey []byte) *SecureCookie {
- s := &SecureCookie{
- hashKey: hashKey,
- blockKey: blockKey,
- hashFunc: sha256.New,
- maxAge: 86400 * 30,
- maxLength: 4096,
- sz: GobEncoder{},
- }
- if len(hashKey) == 0 {
- s.err = errHashKeyNotSet
- }
- if blockKey != nil {
- s.BlockFunc(aes.NewCipher)
- }
- return s
-}
-
-// SecureCookie encodes and decodes authenticated and optionally encrypted
-// cookie values.
-type SecureCookie struct {
- hashKey []byte
- hashFunc func() hash.Hash
- blockKey []byte
- block cipher.Block
- maxLength int
- maxAge int64
- minAge int64
- err error
- sz Serializer
- // For testing purposes, the function that returns the current timestamp.
- // If not set, it will use time.Now().UTC().Unix().
- timeFunc func() int64
-}
-
-// Serializer provides an interface for providing custom serializers for cookie
-// values.
-type Serializer interface {
- Serialize(src interface{}) ([]byte, error)
- Deserialize(src []byte, dst interface{}) error
-}
-
-// GobEncoder encodes cookie values using encoding/gob. This is the simplest
-// encoder and can handle complex types via gob.Register.
-type GobEncoder struct{}
-
-// JSONEncoder encodes cookie values using encoding/json. Users who wish to
-// encode complex types need to satisfy the json.Marshaller and
-// json.Unmarshaller interfaces.
-type JSONEncoder struct{}
-
-// NopEncoder does not encode cookie values, and instead simply accepts a []byte
-// (as an interface{}) and returns a []byte. This is particularly useful when
-// you encoding an object upstream and do not wish to re-encode it.
-type NopEncoder struct{}
-
-// MaxLength restricts the maximum length, in bytes, for the cookie value.
-//
-// Default is 4096, which is the maximum value accepted by Internet Explorer.
-func (s *SecureCookie) MaxLength(value int) *SecureCookie {
- s.maxLength = value
- return s
-}
-
-// MaxAge restricts the maximum age, in seconds, for the cookie value.
-//
-// Default is 86400 * 30. Set it to 0 for no restriction.
-func (s *SecureCookie) MaxAge(value int) *SecureCookie {
- s.maxAge = int64(value)
- return s
-}
-
-// MinAge restricts the minimum age, in seconds, for the cookie value.
-//
-// Default is 0 (no restriction).
-func (s *SecureCookie) MinAge(value int) *SecureCookie {
- s.minAge = int64(value)
- return s
-}
-
-// HashFunc sets the hash function used to create HMAC.
-//
-// Default is crypto/sha256.New.
-func (s *SecureCookie) HashFunc(f func() hash.Hash) *SecureCookie {
- s.hashFunc = f
- return s
-}
-
-// BlockFunc sets the encryption function used to create a cipher.Block.
-//
-// Default is crypto/aes.New.
-func (s *SecureCookie) BlockFunc(f func([]byte) (cipher.Block, error)) *SecureCookie {
- if s.blockKey == nil {
- s.err = errBlockKeyNotSet
- } else if block, err := f(s.blockKey); err == nil {
- s.block = block
- } else {
- s.err = cookieError{cause: err, typ: usageError}
- }
- return s
-}
-
-// Encoding sets the encoding/serialization method for cookies.
-//
-// Default is encoding/gob. To encode special structures using encoding/gob,
-// they must be registered first using gob.Register().
-func (s *SecureCookie) SetSerializer(sz Serializer) *SecureCookie {
- s.sz = sz
-
- return s
-}
-
-// Encode encodes a cookie value.
-//
-// It serializes, optionally encrypts, signs with a message authentication code,
-// and finally encodes the value.
-//
-// The name argument is the cookie name. It is stored with the encoded value.
-// The value argument is the value to be encoded. It can be any value that can
-// be encoded using the currently selected serializer; see SetSerializer().
-//
-// It is the client's responsibility to ensure that value, when encoded using
-// the current serialization/encryption settings on s and then base64-encoded,
-// is shorter than the maximum permissible length.
-func (s *SecureCookie) Encode(name string, value interface{}) (string, error) {
- if s.err != nil {
- return "", s.err
- }
- if s.hashKey == nil {
- s.err = errHashKeyNotSet
- return "", s.err
- }
- var err error
- var b []byte
- // 1. Serialize.
- if b, err = s.sz.Serialize(value); err != nil {
- return "", cookieError{cause: err, typ: usageError}
- }
- // 2. Encrypt (optional).
- if s.block != nil {
- if b, err = encrypt(s.block, b); err != nil {
- return "", cookieError{cause: err, typ: usageError}
- }
- }
- b = encode(b)
- // 3. Create MAC for "name|date|value". Extra pipe to be used later.
- b = []byte(fmt.Sprintf("%s|%d|%s|", name, s.timestamp(), b))
- mac := createMac(hmac.New(s.hashFunc, s.hashKey), b[:len(b)-1])
- // Append mac, remove name.
- b = append(b, mac...)[len(name)+1:]
- // 4. Encode to base64.
- b = encode(b)
- // 5. Check length.
- if s.maxLength != 0 && len(b) > s.maxLength {
- return "", fmt.Errorf("%s: %d", errEncodedValueTooLong, len(b))
- }
- // Done.
- return string(b), nil
-}
-
-// Decode decodes a cookie value.
-//
-// It decodes, verifies a message authentication code, optionally decrypts and
-// finally deserializes the value.
-//
-// The name argument is the cookie name. It must be the same name used when
-// it was stored. The value argument is the encoded cookie value. The dst
-// argument is where the cookie will be decoded. It must be a pointer.
-func (s *SecureCookie) Decode(name, value string, dst interface{}) error {
- if s.err != nil {
- return s.err
- }
- if s.hashKey == nil {
- s.err = errHashKeyNotSet
- return s.err
- }
- // 1. Check length.
- if s.maxLength != 0 && len(value) > s.maxLength {
- return fmt.Errorf("%s: %d", errValueToDecodeTooLong, len(value))
- }
- // 2. Decode from base64.
- b, err := decode([]byte(value))
- if err != nil {
- return err
- }
- // 3. Verify MAC. Value is "date|value|mac".
- parts := bytes.SplitN(b, []byte("|"), 3)
- if len(parts) != 3 {
- return ErrMacInvalid
- }
- h := hmac.New(s.hashFunc, s.hashKey)
- b = append([]byte(name+"|"), b[:len(b)-len(parts[2])-1]...)
- if err = verifyMac(h, b, parts[2]); err != nil {
- return err
- }
- // 4. Verify date ranges.
- var t1 int64
- if t1, err = strconv.ParseInt(string(parts[0]), 10, 64); err != nil {
- return errTimestampInvalid
- }
- t2 := s.timestamp()
- if s.minAge != 0 && t1 > t2-s.minAge {
- return errTimestampTooNew
- }
- if s.maxAge != 0 && t1 < t2-s.maxAge {
- return errTimestampExpired
- }
- // 5. Decrypt (optional).
- b, err = decode(parts[1])
- if err != nil {
- return err
- }
- if s.block != nil {
- if b, err = decrypt(s.block, b); err != nil {
- return err
- }
- }
- // 6. Deserialize.
- if err = s.sz.Deserialize(b, dst); err != nil {
- return cookieError{cause: err, typ: decodeError}
- }
- // Done.
- return nil
-}
-
-// timestamp returns the current timestamp, in seconds.
-//
-// For testing purposes, the function that generates the timestamp can be
-// overridden. If not set, it will return time.Now().UTC().Unix().
-func (s *SecureCookie) timestamp() int64 {
- if s.timeFunc == nil {
- return time.Now().UTC().Unix()
- }
- return s.timeFunc()
-}
-
-// Authentication -------------------------------------------------------------
-
-// createMac creates a message authentication code (MAC).
-func createMac(h hash.Hash, value []byte) []byte {
- h.Write(value)
- return h.Sum(nil)
-}
-
-// verifyMac verifies that a message authentication code (MAC) is valid.
-func verifyMac(h hash.Hash, value []byte, mac []byte) error {
- mac2 := createMac(h, value)
- // Check that both MACs are of equal length, as subtle.ConstantTimeCompare
- // does not do this prior to Go 1.4.
- if len(mac) == len(mac2) && subtle.ConstantTimeCompare(mac, mac2) == 1 {
- return nil
- }
- return ErrMacInvalid
-}
-
-// Encryption -----------------------------------------------------------------
-
-// encrypt encrypts a value using the given block in counter mode.
-//
-// A random initialization vector ( https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_(IV) ) with the length of the
-// block size is prepended to the resulting ciphertext.
-func encrypt(block cipher.Block, value []byte) ([]byte, error) {
- iv := GenerateRandomKey(block.BlockSize())
- if iv == nil {
- return nil, errGeneratingIV
- }
- // Encrypt it.
- stream := cipher.NewCTR(block, iv)
- stream.XORKeyStream(value, value)
- // Return iv + ciphertext.
- return append(iv, value...), nil
-}
-
-// decrypt decrypts a value using the given block in counter mode.
-//
-// The value to be decrypted must be prepended by a initialization vector
-// ( https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_(IV) ) with the length of the block size.
-func decrypt(block cipher.Block, value []byte) ([]byte, error) {
- size := block.BlockSize()
- if len(value) > size {
- // Extract iv.
- iv := value[:size]
- // Extract ciphertext.
- value = value[size:]
- // Decrypt it.
- stream := cipher.NewCTR(block, iv)
- stream.XORKeyStream(value, value)
- return value, nil
- }
- return nil, errDecryptionFailed
-}
-
-// Serialization --------------------------------------------------------------
-
-// Serialize encodes a value using gob.
-func (e GobEncoder) Serialize(src interface{}) ([]byte, error) {
- buf := new(bytes.Buffer)
- enc := gob.NewEncoder(buf)
- if err := enc.Encode(src); err != nil {
- return nil, cookieError{cause: err, typ: usageError}
- }
- return buf.Bytes(), nil
-}
-
-// Deserialize decodes a value using gob.
-func (e GobEncoder) Deserialize(src []byte, dst interface{}) error {
- dec := gob.NewDecoder(bytes.NewBuffer(src))
- if err := dec.Decode(dst); err != nil {
- return cookieError{cause: err, typ: decodeError}
- }
- return nil
-}
-
-// Serialize encodes a value using encoding/json.
-func (e JSONEncoder) Serialize(src interface{}) ([]byte, error) {
- buf := new(bytes.Buffer)
- enc := json.NewEncoder(buf)
- if err := enc.Encode(src); err != nil {
- return nil, cookieError{cause: err, typ: usageError}
- }
- return buf.Bytes(), nil
-}
-
-// Deserialize decodes a value using encoding/json.
-func (e JSONEncoder) Deserialize(src []byte, dst interface{}) error {
- dec := json.NewDecoder(bytes.NewReader(src))
- if err := dec.Decode(dst); err != nil {
- return cookieError{cause: err, typ: decodeError}
- }
- return nil
-}
-
-// Serialize passes a []byte through as-is.
-func (e NopEncoder) Serialize(src interface{}) ([]byte, error) {
- if b, ok := src.([]byte); ok {
- return b, nil
- }
-
- return nil, errValueNotByte
-}
-
-// Deserialize passes a []byte through as-is.
-func (e NopEncoder) Deserialize(src []byte, dst interface{}) error {
- if dat, ok := dst.(*[]byte); ok {
- *dat = src
- return nil
- }
- return errValueNotBytePtr
-}
-
-// Encoding -------------------------------------------------------------------
-
-// encode encodes a value using base64.
-func encode(value []byte) []byte {
- encoded := make([]byte, base64.URLEncoding.EncodedLen(len(value)))
- base64.URLEncoding.Encode(encoded, value)
- return encoded
-}
-
-// decode decodes a cookie using base64.
-func decode(value []byte) ([]byte, error) {
- decoded := make([]byte, base64.URLEncoding.DecodedLen(len(value)))
- b, err := base64.URLEncoding.Decode(decoded, value)
- if err != nil {
- return nil, cookieError{cause: err, typ: decodeError, msg: "base64 decode failed"}
- }
- return decoded[:b], nil
-}
-
-// Helpers --------------------------------------------------------------------
-
-// GenerateRandomKey creates a random key with the given length in bytes.
-// On failure, returns nil.
-//
-// Note that keys created using `GenerateRandomKey()` are not automatically
-// persisted. New keys will be created when the application is restarted, and
-// previously issued cookies will not be able to be decoded.
-//
-// Callers should explicitly check for the possibility of a nil return, treat
-// it as a failure of the system random number generator, and not continue.
-func GenerateRandomKey(length int) []byte {
- k := make([]byte, length)
- if _, err := io.ReadFull(rand.Reader, k); err != nil {
- return nil
- }
- return k
-}
-
-// CodecsFromPairs returns a slice of SecureCookie instances.
-//
-// It is a convenience function to create a list of codecs for key rotation. Note
-// that the generated Codecs will have the default options applied: callers
-// should iterate over each Codec and type-assert the underlying *SecureCookie to
-// change these.
-//
-// Example:
-//
-// codecs := securecookie.CodecsFromPairs(
-// []byte("new-hash-key"),
-// []byte("new-block-key"),
-// []byte("old-hash-key"),
-// []byte("old-block-key"),
-// )
-//
-// // Modify each instance.
-// for _, s := range codecs {
-// if cookie, ok := s.(*securecookie.SecureCookie); ok {
-// cookie.MaxAge(86400 * 7)
-// cookie.SetSerializer(securecookie.JSONEncoder{})
-// cookie.HashFunc(sha512.New512_256)
-// }
-// }
-func CodecsFromPairs(keyPairs ...[]byte) []Codec {
- codecs := make([]Codec, len(keyPairs)/2+len(keyPairs)%2)
- for i := 0; i < len(keyPairs); i += 2 {
- var blockKey []byte
- if i+1 < len(keyPairs) {
- blockKey = keyPairs[i+1]
- }
- codecs[i/2] = New(keyPairs[i], blockKey)
- }
- return codecs
-}
-
-// EncodeMulti encodes a cookie value using a group of codecs.
-//
-// The codecs are tried in order. Multiple codecs are accepted to allow
-// key rotation.
-//
-// On error, may return a MultiError.
-func EncodeMulti(name string, value interface{}, codecs ...Codec) (string, error) {
- if len(codecs) == 0 {
- return "", errNoCodecs
- }
-
- var errors MultiError
- for _, codec := range codecs {
- encoded, err := codec.Encode(name, value)
- if err == nil {
- return encoded, nil
- }
- errors = append(errors, err)
- }
- return "", errors
-}
-
-// DecodeMulti decodes a cookie value using a group of codecs.
-//
-// The codecs are tried in order. Multiple codecs are accepted to allow
-// key rotation.
-//
-// On error, may return a MultiError.
-func DecodeMulti(name string, value string, dst interface{}, codecs ...Codec) error {
- if len(codecs) == 0 {
- return errNoCodecs
- }
-
- var errors MultiError
- for _, codec := range codecs {
- err := codec.Decode(name, value, dst)
- if err == nil {
- return nil
- }
- errors = append(errors, err)
- }
- return errors
-}
-
-// MultiError groups multiple errors.
-type MultiError []error
-
-func (m MultiError) IsUsage() bool { return m.any(func(e Error) bool { return e.IsUsage() }) }
-func (m MultiError) IsDecode() bool { return m.any(func(e Error) bool { return e.IsDecode() }) }
-func (m MultiError) IsInternal() bool { return m.any(func(e Error) bool { return e.IsInternal() }) }
-
-// Cause returns nil for MultiError; there is no unique underlying cause in the
-// general case.
-//
-// Note: we could conceivably return a non-nil Cause only when there is exactly
-// one child error with a Cause. However, it would be brittle for client code
-// to rely on the arity of causes inside a MultiError, so we have opted not to
-// provide this functionality. Clients which really wish to access the Causes
-// of the underlying errors are free to iterate through the errors themselves.
-func (m MultiError) Cause() error { return nil }
-
-func (m MultiError) Error() string {
- s, n := "", 0
- for _, e := range m {
- if e != nil {
- if n == 0 {
- s = e.Error()
- }
- n++
- }
- }
- switch n {
- case 0:
- return "(0 errors)"
- case 1:
- return s
- case 2:
- return s + " (and 1 other error)"
- }
- return fmt.Sprintf("%s (and %d other errors)", s, n-1)
-}
-
-// any returns true if any element of m is an Error for which pred returns true.
-func (m MultiError) any(pred func(Error) bool) bool {
- for _, e := range m {
- if ourErr, ok := e.(Error); ok && pred(ourErr) {
- return true
- }
- }
- return false
-}
diff --git a/vendor/github.com/gorilla/sessions/.editorconfig b/vendor/github.com/gorilla/sessions/.editorconfig
deleted file mode 100644
index 2940ec92a..000000000
--- a/vendor/github.com/gorilla/sessions/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-; https://editorconfig.org/
-
-root = true
-
-[*]
-insert_final_newline = true
-charset = utf-8
-trim_trailing_whitespace = true
-indent_style = space
-indent_size = 2
-
-[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
-indent_style = tab
-indent_size = 4
-
-[*.md]
-indent_size = 4
-trim_trailing_whitespace = false
-
-eclint_indent_style = unset
diff --git a/vendor/github.com/gorilla/sessions/.gitignore b/vendor/github.com/gorilla/sessions/.gitignore
deleted file mode 100644
index 84039fec6..000000000
--- a/vendor/github.com/gorilla/sessions/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-coverage.coverprofile
diff --git a/vendor/github.com/gorilla/sessions/LICENSE b/vendor/github.com/gorilla/sessions/LICENSE
deleted file mode 100644
index bb9d80bc9..000000000
--- a/vendor/github.com/gorilla/sessions/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2023 The Gorilla Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gorilla/sessions/Makefile b/vendor/github.com/gorilla/sessions/Makefile
deleted file mode 100644
index ac37ffd32..000000000
--- a/vendor/github.com/gorilla/sessions/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
-GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
-
-GO_SEC=$(shell which gosec 2> /dev/null || echo '')
-GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
-
-GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
-GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
-
-.PHONY: golangci-lint
-golangci-lint:
- $(if $(GO_LINT), ,go install $(GO_LINT_URI))
- @echo "##### Running golangci-lint"
- golangci-lint run -v
-
-.PHONY: gosec
-gosec:
- $(if $(GO_SEC), ,go install $(GO_SEC_URI))
- @echo "##### Running gosec"
- gosec ./...
-
-.PHONY: govulncheck
-govulncheck:
- $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
- @echo "##### Running govulncheck"
- govulncheck ./...
-
-.PHONY: verify
-verify: golangci-lint gosec govulncheck
-
-.PHONY: test
-test:
- @echo "##### Running tests"
- go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
diff --git a/vendor/github.com/gorilla/sessions/README.md b/vendor/github.com/gorilla/sessions/README.md
deleted file mode 100644
index 06119bbbe..000000000
--- a/vendor/github.com/gorilla/sessions/README.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# sessions
-
-![testing](https://github.com/gorilla/sessions/actions/workflows/test.yml/badge.svg)
-[![codecov](https://codecov.io/github/gorilla/sessions/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/sessions)
-[![godoc](https://godoc.org/github.com/gorilla/sessions?status.svg)](https://godoc.org/github.com/gorilla/sessions)
-[![sourcegraph](https://sourcegraph.com/github.com/gorilla/sessions/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/sessions?badge)
-
-![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5)
-
-gorilla/sessions provides cookie and filesystem sessions and infrastructure for
-custom session backends.
-
-The key features are:
-
-- Simple API: use it as an easy way to set signed (and optionally
- encrypted) cookies.
-- Built-in backends to store sessions in cookies or the filesystem.
-- Flash messages: session values that last until read.
-- Convenient way to switch session persistency (aka "remember me") and set
- other attributes.
-- Mechanism to rotate authentication and encryption keys.
-- Multiple sessions per request, even using different backends.
-- Interfaces and infrastructure for custom session backends: sessions from
- different stores can be retrieved and batch-saved using a common API.
-
-Let's start with an example that shows the sessions API in a nutshell:
-
-```go
- import (
- "net/http"
- "github.com/gorilla/sessions"
- )
-
- // Note: Don't store your key in your source code. Pass it via an
- // environmental variable, or flag (or both), and don't accidentally commit it
- // alongside your code. Ensure your key is sufficiently random - i.e. use Go's
- // crypto/rand or securecookie.GenerateRandomKey(32) and persist the result.
- var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))
-
- func MyHandler(w http.ResponseWriter, r *http.Request) {
- // Get a session. We're ignoring the error resulted from decoding an
- // existing session: Get() always returns a session, even if empty.
- session, _ := store.Get(r, "session-name")
- // Set some session values.
- session.Values["foo"] = "bar"
- session.Values[42] = 43
- // Save it before we write to the response/return from the handler.
- err := session.Save(r, w)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- }
-```
-
-First we initialize a session store calling `NewCookieStore()` and passing a
-secret key used to authenticate the session. Inside the handler, we call
-`store.Get()` to retrieve an existing session or create a new one. Then we set
-some session values in session.Values, which is a `map[interface{}]interface{}`.
-And finally we call `session.Save()` to save the session in the response.
-
-More examples are available [on the Gorilla
-website](https://www.gorillatoolkit.org/pkg/sessions).
-
-## Store Implementations
-
-Other implementations of the `sessions.Store` interface:
-
-- [github.com/starJammer/gorilla-sessions-arangodb](https://github.com/starJammer/gorilla-sessions-arangodb) - ArangoDB
-- [github.com/yosssi/boltstore](https://github.com/yosssi/boltstore) - Bolt
-- [github.com/srinathgs/couchbasestore](https://github.com/srinathgs/couchbasestore) - Couchbase
-- [github.com/denizeren/dynamostore](https://github.com/denizeren/dynamostore) - Dynamodb on AWS
-- [github.com/savaki/dynastore](https://github.com/savaki/dynastore) - DynamoDB on AWS (Official AWS library)
-- [github.com/bradleypeabody/gorilla-sessions-memcache](https://github.com/bradleypeabody/gorilla-sessions-memcache) - Memcache
-- [github.com/dsoprea/go-appengine-sessioncascade](https://github.com/dsoprea/go-appengine-sessioncascade) - Memcache/Datastore/Context in AppEngine
-- [github.com/kidstuff/mongostore](https://github.com/kidstuff/mongostore) - MongoDB
-- [github.com/srinathgs/mysqlstore](https://github.com/srinathgs/mysqlstore) - MySQL
-- [github.com/EnumApps/clustersqlstore](https://github.com/EnumApps/clustersqlstore) - MySQL Cluster
-- [github.com/antonlindstrom/pgstore](https://github.com/antonlindstrom/pgstore) - PostgreSQL
-- [github.com/boj/redistore](https://github.com/boj/redistore) - Redis
-- [github.com/rbcervilla/redisstore](https://github.com/rbcervilla/redisstore) - Redis (Single, Sentinel, Cluster)
-- [github.com/boj/rethinkstore](https://github.com/boj/rethinkstore) - RethinkDB
-- [github.com/boj/riakstore](https://github.com/boj/riakstore) - Riak
-- [github.com/michaeljs1990/sqlitestore](https://github.com/michaeljs1990/sqlitestore) - SQLite
-- [github.com/wader/gormstore](https://github.com/wader/gormstore) - GORM (MySQL, PostgreSQL, SQLite)
-- [github.com/gernest/qlstore](https://github.com/gernest/qlstore) - ql
-- [github.com/quasoft/memstore](https://github.com/quasoft/memstore) - In-memory implementation for use in unit tests
-- [github.com/lafriks/xormstore](https://github.com/lafriks/xormstore) - XORM (MySQL, PostgreSQL, SQLite, Microsoft SQL Server, TiDB)
-- [github.com/GoogleCloudPlatform/firestore-gorilla-sessions](https://github.com/GoogleCloudPlatform/firestore-gorilla-sessions) - Cloud Firestore
-- [github.com/stephenafamo/crdbstore](https://github.com/stephenafamo/crdbstore) - CockroachDB
-- [github.com/ryicoh/tikvstore](github.com/ryicoh/tikvstore) - TiKV
-
-## License
-
-BSD licensed. See the LICENSE file for details.
diff --git a/vendor/github.com/gorilla/sessions/cookie.go b/vendor/github.com/gorilla/sessions/cookie.go
deleted file mode 100644
index 6612662cc..000000000
--- a/vendor/github.com/gorilla/sessions/cookie.go
+++ /dev/null
@@ -1,20 +0,0 @@
-//go:build !go1.11
-// +build !go1.11
-
-package sessions
-
-import "net/http"
-
-// newCookieFromOptions returns an http.Cookie with the options set.
-func newCookieFromOptions(name, value string, options *Options) *http.Cookie {
- return &http.Cookie{
- Name: name,
- Value: value,
- Path: options.Path,
- Domain: options.Domain,
- MaxAge: options.MaxAge,
- Secure: options.Secure,
- HttpOnly: options.HttpOnly,
- }
-
-}
diff --git a/vendor/github.com/gorilla/sessions/cookie_go111.go b/vendor/github.com/gorilla/sessions/cookie_go111.go
deleted file mode 100644
index 9b5882835..000000000
--- a/vendor/github.com/gorilla/sessions/cookie_go111.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build go1.11
-// +build go1.11
-
-package sessions
-
-import "net/http"
-
-// newCookieFromOptions returns an http.Cookie with the options set.
-func newCookieFromOptions(name, value string, options *Options) *http.Cookie {
- return &http.Cookie{
- Name: name,
- Value: value,
- Path: options.Path,
- Domain: options.Domain,
- MaxAge: options.MaxAge,
- Secure: options.Secure,
- HttpOnly: options.HttpOnly,
- SameSite: options.SameSite,
- }
-
-}
diff --git a/vendor/github.com/gorilla/sessions/doc.go b/vendor/github.com/gorilla/sessions/doc.go
deleted file mode 100644
index 946bf5ca1..000000000
--- a/vendor/github.com/gorilla/sessions/doc.go
+++ /dev/null
@@ -1,207 +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 sessions provides cookie and filesystem sessions and
-infrastructure for custom session backends.
-
-The key features are:
-
- * Simple API: use it as an easy way to set signed (and optionally
- encrypted) cookies.
- * Built-in backends to store sessions in cookies or the filesystem.
- * Flash messages: session values that last until read.
- * Convenient way to switch session persistency (aka "remember me") and set
- other attributes.
- * Mechanism to rotate authentication and encryption keys.
- * Multiple sessions per request, even using different backends.
- * Interfaces and infrastructure for custom session backends: sessions from
- different stores can be retrieved and batch-saved using a common API.
-
-Let's start with an example that shows the sessions API in a nutshell:
-
- import (
- "net/http"
- "github.com/gorilla/sessions"
- )
-
- // Note: Don't store your key in your source code. Pass it via an
- // environmental variable, or flag (or both), and don't accidentally commit it
- // alongside your code. Ensure your key is sufficiently random - i.e. use Go's
- // crypto/rand or securecookie.GenerateRandomKey(32) and persist the result.
- // Ensure SESSION_KEY exists in the environment, or sessions will fail.
- var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))
-
- func MyHandler(w http.ResponseWriter, r *http.Request) {
- // Get a session. Get() always returns a session, even if empty.
- session, err := store.Get(r, "session-name")
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- // Set some session values.
- session.Values["foo"] = "bar"
- session.Values[42] = 43
- // Save it before we write to the response/return from the handler.
- err = session.Save(r, w)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- }
-
-First we initialize a session store calling NewCookieStore() and passing a
-secret key used to authenticate the session. Inside the handler, we call
-store.Get() to retrieve an existing session or a new one. Then we set some
-session values in session.Values, which is a map[interface{}]interface{}.
-And finally we call session.Save() to save the session in the response.
-
-Note that in production code, we should check for errors when calling
-session.Save(r, w), and either display an error message or otherwise handle it.
-
-Save must be called before writing to the response, otherwise the session
-cookie will not be sent to the client.
-
-That's all you need to know for the basic usage. Let's take a look at other
-options, starting with flash messages.
-
-Flash messages are session values that last until read. The term appeared with
-Ruby On Rails a few years back. When we request a flash message, it is removed
-from the session. To add a flash, call session.AddFlash(), and to get all
-flashes, call session.Flashes(). Here is an example:
-
- func MyHandler(w http.ResponseWriter, r *http.Request) {
- // Get a session.
- session, err := store.Get(r, "session-name")
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- // Get the previous flashes, if any.
- if flashes := session.Flashes(); len(flashes) > 0 {
- // Use the flash values.
- } else {
- // Set a new flash.
- session.AddFlash("Hello, flash messages world!")
- }
- err = session.Save(r, w)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- }
-
-Flash messages are useful to set information to be read after a redirection,
-like after form submissions.
-
-There may also be cases where you want to store a complex datatype within a
-session, such as a struct. Sessions are serialised using the encoding/gob package,
-so it is easy to register new datatypes for storage in sessions:
-
- import(
- "encoding/gob"
- "github.com/gorilla/sessions"
- )
-
- type Person struct {
- FirstName string
- LastName string
- Email string
- Age int
- }
-
- type M map[string]interface{}
-
- func init() {
-
- gob.Register(&Person{})
- gob.Register(&M{})
- }
-
-As it's not possible to pass a raw type as a parameter to a function, gob.Register()
-relies on us passing it a value of the desired type. In the example above we've passed
-it a pointer to a struct and a pointer to a custom type representing a
-map[string]interface. (We could have passed non-pointer values if we wished.) This will
-then allow us to serialise/deserialise values of those types to and from our sessions.
-
-Note that because session values are stored in a map[string]interface{}, there's
-a need to type-assert data when retrieving it. We'll use the Person struct we registered above:
-
- func MyHandler(w http.ResponseWriter, r *http.Request) {
- session, err := store.Get(r, "session-name")
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- // Retrieve our struct and type-assert it
- val := session.Values["person"]
- var person = &Person{}
- if person, ok := val.(*Person); !ok {
- // Handle the case that it's not an expected type
- }
-
- // Now we can use our person object
- }
-
-By default, session cookies last for a month. This is probably too long for
-some cases, but it is easy to change this and other attributes during
-runtime. Sessions can be configured individually or the store can be
-configured and then all sessions saved using it will use that configuration.
-We access session.Options or store.Options to set a new configuration. The
-fields are basically a subset of http.Cookie fields. Let's change the
-maximum age of a session to one week:
-
- session.Options = &sessions.Options{
- Path: "/",
- MaxAge: 86400 * 7,
- HttpOnly: true,
- }
-
-Sometimes we may want to change authentication and/or encryption keys without
-breaking existing sessions. The CookieStore supports key rotation, and to use
-it you just need to set multiple authentication and encryption keys, in pairs,
-to be tested in order:
-
- var store = sessions.NewCookieStore(
- []byte("new-authentication-key"),
- []byte("new-encryption-key"),
- []byte("old-authentication-key"),
- []byte("old-encryption-key"),
- )
-
-New sessions will be saved using the first pair. Old sessions can still be
-read because the first pair will fail, and the second will be tested. This
-makes it easy to "rotate" secret keys and still be able to validate existing
-sessions. Note: for all pairs the encryption key is optional; set it to nil
-or omit it and and encryption won't be used.
-
-Multiple sessions can be used in the same request, even with different
-session backends. When this happens, calling Save() on each session
-individually would be cumbersome, so we have a way to save all sessions
-at once: it's sessions.Save(). Here's an example:
-
- var store = sessions.NewCookieStore([]byte("something-very-secret"))
-
- func MyHandler(w http.ResponseWriter, r *http.Request) {
- // Get a session and set a value.
- session1, _ := store.Get(r, "session-one")
- session1.Values["foo"] = "bar"
- // Get another session and set another value.
- session2, _ := store.Get(r, "session-two")
- session2.Values[42] = 43
- // Save all sessions.
- err = sessions.Save(r, w)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- }
-
-This is possible because when we call Get() from a session store, it adds the
-session to a common registry. Save() uses it to save all registered sessions.
-*/
-package sessions
diff --git a/vendor/github.com/gorilla/sessions/lex.go b/vendor/github.com/gorilla/sessions/lex.go
deleted file mode 100644
index 4bbbe1096..000000000
--- a/vendor/github.com/gorilla/sessions/lex.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// This file contains code adapted from the Go standard library
-// https://github.com/golang/go/blob/39ad0fd0789872f9469167be7fe9578625ff246e/src/net/http/lex.go
-
-package sessions
-
-import "strings"
-
-var isTokenTable = [127]bool{
- '!': true,
- '#': true,
- '$': true,
- '%': true,
- '&': true,
- '\'': true,
- '*': true,
- '+': true,
- '-': true,
- '.': true,
- '0': true,
- '1': true,
- '2': true,
- '3': true,
- '4': true,
- '5': true,
- '6': true,
- '7': true,
- '8': true,
- '9': true,
- 'A': true,
- 'B': true,
- 'C': true,
- 'D': true,
- 'E': true,
- 'F': true,
- 'G': true,
- 'H': true,
- 'I': true,
- 'J': true,
- 'K': true,
- 'L': true,
- 'M': true,
- 'N': true,
- 'O': true,
- 'P': true,
- 'Q': true,
- 'R': true,
- 'S': true,
- 'T': true,
- 'U': true,
- 'W': true,
- 'V': true,
- 'X': true,
- 'Y': true,
- 'Z': true,
- '^': true,
- '_': true,
- '`': true,
- 'a': true,
- 'b': true,
- 'c': true,
- 'd': true,
- 'e': true,
- 'f': true,
- 'g': true,
- 'h': true,
- 'i': true,
- 'j': true,
- 'k': true,
- 'l': true,
- 'm': true,
- 'n': true,
- 'o': true,
- 'p': true,
- 'q': true,
- 'r': true,
- 's': true,
- 't': true,
- 'u': true,
- 'v': true,
- 'w': true,
- 'x': true,
- 'y': true,
- 'z': true,
- '|': true,
- '~': true,
-}
-
-func isToken(r rune) bool {
- i := int(r)
- return i < len(isTokenTable) && isTokenTable[i]
-}
-
-func isNotToken(r rune) bool {
- return !isToken(r)
-}
-
-func isCookieNameValid(raw string) bool {
- if raw == "" {
- return false
- }
- return strings.IndexFunc(raw, isNotToken) < 0
-}
diff --git a/vendor/github.com/gorilla/sessions/options.go b/vendor/github.com/gorilla/sessions/options.go
deleted file mode 100644
index d33d0761a..000000000
--- a/vendor/github.com/gorilla/sessions/options.go
+++ /dev/null
@@ -1,19 +0,0 @@
-//go:build !go1.11
-// +build !go1.11
-
-package sessions
-
-// Options stores configuration for a session or session store.
-//
-// Fields are a subset of http.Cookie fields.
-type Options struct {
- Path string
- Domain string
- // MaxAge=0 means no Max-Age attribute specified and the cookie will be
- // deleted after the browser session ends.
- // MaxAge<0 means delete cookie immediately.
- // MaxAge>0 means Max-Age attribute present and given in seconds.
- MaxAge int
- Secure bool
- HttpOnly bool
-}
diff --git a/vendor/github.com/gorilla/sessions/options_go111.go b/vendor/github.com/gorilla/sessions/options_go111.go
deleted file mode 100644
index af9cdf08d..000000000
--- a/vendor/github.com/gorilla/sessions/options_go111.go
+++ /dev/null
@@ -1,23 +0,0 @@
-//go:build go1.11
-// +build go1.11
-
-package sessions
-
-import "net/http"
-
-// Options stores configuration for a session or session store.
-//
-// Fields are a subset of http.Cookie fields.
-type Options struct {
- Path string
- Domain string
- // MaxAge=0 means no Max-Age attribute specified and the cookie will be
- // deleted after the browser session ends.
- // MaxAge<0 means delete cookie immediately.
- // MaxAge>0 means Max-Age attribute present and given in seconds.
- MaxAge int
- Secure bool
- HttpOnly bool
- // Defaults to http.SameSiteDefaultMode
- SameSite http.SameSite
-}
diff --git a/vendor/github.com/gorilla/sessions/sessions.go b/vendor/github.com/gorilla/sessions/sessions.go
deleted file mode 100644
index c052b2891..000000000
--- a/vendor/github.com/gorilla/sessions/sessions.go
+++ /dev/null
@@ -1,218 +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 sessions
-
-import (
- "context"
- "encoding/gob"
- "fmt"
- "net/http"
- "time"
-)
-
-// Default flashes key.
-const flashesKey = "_flash"
-
-// Session --------------------------------------------------------------------
-
-// NewSession is called by session stores to create a new session instance.
-func NewSession(store Store, name string) *Session {
- return &Session{
- Values: make(map[interface{}]interface{}),
- store: store,
- name: name,
- Options: new(Options),
- }
-}
-
-// Session stores the values and optional configuration for a session.
-type Session struct {
- // The ID of the session, generated by stores. It should not be used for
- // user data.
- ID string
- // Values contains the user-data for the session.
- Values map[interface{}]interface{}
- Options *Options
- IsNew bool
- store Store
- name string
-}
-
-// Flashes returns a slice of flash messages from the session.
-//
-// A single variadic argument is accepted, and it is optional: it defines
-// the flash key. If not defined "_flash" is used by default.
-func (s *Session) Flashes(vars ...string) []interface{} {
- var flashes []interface{}
- key := flashesKey
- if len(vars) > 0 {
- key = vars[0]
- }
- if v, ok := s.Values[key]; ok {
- // Drop the flashes and return it.
- delete(s.Values, key)
- flashes = v.([]interface{})
- }
- return flashes
-}
-
-// AddFlash adds a flash message to the session.
-//
-// A single variadic argument is accepted, and it is optional: it defines
-// the flash key. If not defined "_flash" is used by default.
-func (s *Session) AddFlash(value interface{}, vars ...string) {
- key := flashesKey
- if len(vars) > 0 {
- key = vars[0]
- }
- var flashes []interface{}
- if v, ok := s.Values[key]; ok {
- flashes = v.([]interface{})
- }
- s.Values[key] = append(flashes, value)
-}
-
-// Save is a convenience method to save this session. It is the same as calling
-// store.Save(request, response, session). You should call Save before writing to
-// the response or returning from the handler.
-func (s *Session) Save(r *http.Request, w http.ResponseWriter) error {
- return s.store.Save(r, w, s)
-}
-
-// Name returns the name used to register the session.
-func (s *Session) Name() string {
- return s.name
-}
-
-// Store returns the session store used to register the session.
-func (s *Session) Store() Store {
- return s.store
-}
-
-// Registry -------------------------------------------------------------------
-
-// sessionInfo stores a session tracked by the registry.
-type sessionInfo struct {
- s *Session
- e error
-}
-
-// contextKey is the type used to store the registry in the context.
-type contextKey int
-
-// registryKey is the key used to store the registry in the context.
-const registryKey contextKey = 0
-
-// GetRegistry returns a registry instance for the current request.
-func GetRegistry(r *http.Request) *Registry {
- var ctx = r.Context()
- registry := ctx.Value(registryKey)
- if registry != nil {
- return registry.(*Registry)
- }
- newRegistry := &Registry{
- request: r,
- sessions: make(map[string]sessionInfo),
- }
- *r = *r.WithContext(context.WithValue(ctx, registryKey, newRegistry))
- return newRegistry
-}
-
-// Registry stores sessions used during a request.
-type Registry struct {
- request *http.Request
- sessions map[string]sessionInfo
-}
-
-// Get registers and returns a session for the given name and session store.
-//
-// It returns a new session if there are no sessions registered for the name.
-func (s *Registry) Get(store Store, name string) (session *Session, err error) {
- if !isCookieNameValid(name) {
- return nil, fmt.Errorf("sessions: invalid character in cookie name: %s", name)
- }
- if info, ok := s.sessions[name]; ok {
- session, err = info.s, info.e
- } else {
- session, err = store.New(s.request, name)
- session.name = name
- s.sessions[name] = sessionInfo{s: session, e: err}
- }
- session.store = store
- return
-}
-
-// Save saves all sessions registered for the current request.
-func (s *Registry) Save(w http.ResponseWriter) error {
- var errMulti MultiError
- for name, info := range s.sessions {
- session := info.s
- if session.store == nil {
- errMulti = append(errMulti, fmt.Errorf(
- "sessions: missing store for session %q", name))
- } else if err := session.store.Save(s.request, w, session); err != nil {
- errMulti = append(errMulti, fmt.Errorf(
- "sessions: error saving session %q -- %v", name, err))
- }
- }
- if errMulti != nil {
- return errMulti
- }
- return nil
-}
-
-// Helpers --------------------------------------------------------------------
-
-func init() {
- gob.Register([]interface{}{})
-}
-
-// Save saves all sessions used during the current request.
-func Save(r *http.Request, w http.ResponseWriter) error {
- return GetRegistry(r).Save(w)
-}
-
-// NewCookie returns an http.Cookie with the options set. It also sets
-// the Expires field calculated based on the MaxAge value, for Internet
-// Explorer compatibility.
-func NewCookie(name, value string, options *Options) *http.Cookie {
- cookie := newCookieFromOptions(name, value, options)
- if options.MaxAge > 0 {
- d := time.Duration(options.MaxAge) * time.Second
- cookie.Expires = time.Now().Add(d)
- } else if options.MaxAge < 0 {
- // Set it to the past to expire now.
- cookie.Expires = time.Unix(1, 0)
- }
- return cookie
-}
-
-// Error ----------------------------------------------------------------------
-
-// MultiError stores multiple errors.
-//
-// Borrowed from the App Engine SDK.
-type MultiError []error
-
-func (m MultiError) Error() string {
- s, n := "", 0
- for _, e := range m {
- if e != nil {
- if n == 0 {
- s = e.Error()
- }
- n++
- }
- }
- switch n {
- case 0:
- return "(0 errors)"
- case 1:
- return s
- case 2:
- return s + " (and 1 other error)"
- }
- return fmt.Sprintf("%s (and %d other errors)", s, n-1)
-}
diff --git a/vendor/github.com/gorilla/sessions/store.go b/vendor/github.com/gorilla/sessions/store.go
deleted file mode 100644
index aea37e4b5..000000000
--- a/vendor/github.com/gorilla/sessions/store.go
+++ /dev/null
@@ -1,291 +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 sessions
-
-import (
- "encoding/base32"
- "net/http"
- "os"
- "path/filepath"
- "sync"
-
- "github.com/gorilla/securecookie"
-)
-
-// Store is an interface for custom session stores.
-//
-// See CookieStore and FilesystemStore for examples.
-type Store interface {
- // Get should return a cached session.
- Get(r *http.Request, name string) (*Session, error)
-
- // New should create and return a new session.
- //
- // Note that New should never return a nil session, even in the case of
- // an error if using the Registry infrastructure to cache the session.
- New(r *http.Request, name string) (*Session, error)
-
- // Save should persist session to the underlying store implementation.
- Save(r *http.Request, w http.ResponseWriter, s *Session) error
-}
-
-// CookieStore ----------------------------------------------------------------
-
-// NewCookieStore returns a new CookieStore.
-//
-// Keys are defined in pairs to allow key rotation, but the common case is
-// to set a single authentication key and optionally an encryption key.
-//
-// The first key in a pair is used for authentication and the second for
-// encryption. The encryption key can be set to nil or omitted in the last
-// pair, but the authentication key is required in all pairs.
-//
-// It is recommended to use an authentication key with 32 or 64 bytes.
-// The encryption key, if set, must be either 16, 24, or 32 bytes to select
-// AES-128, AES-192, or AES-256 modes.
-func NewCookieStore(keyPairs ...[]byte) *CookieStore {
- cs := &CookieStore{
- Codecs: securecookie.CodecsFromPairs(keyPairs...),
- Options: &Options{
- Path: "/",
- MaxAge: 86400 * 30,
- },
- }
-
- cs.MaxAge(cs.Options.MaxAge)
- return cs
-}
-
-// CookieStore stores sessions using secure cookies.
-type CookieStore struct {
- Codecs []securecookie.Codec
- Options *Options // default configuration
-}
-
-// Get returns a session for the given name after adding it to the registry.
-//
-// It returns a new session if the sessions doesn't exist. Access IsNew on
-// the session to check if it is an existing session or a new one.
-//
-// It returns a new session and an error if the session exists but could
-// not be decoded.
-func (s *CookieStore) Get(r *http.Request, name string) (*Session, error) {
- return GetRegistry(r).Get(s, name)
-}
-
-// New returns a session for the given name without adding it to the registry.
-//
-// The difference between New() and Get() is that calling New() twice will
-// decode the session data twice, while Get() registers and reuses the same
-// decoded session after the first call.
-func (s *CookieStore) New(r *http.Request, name string) (*Session, error) {
- session := NewSession(s, name)
- opts := *s.Options
- session.Options = &opts
- session.IsNew = true
- var err error
- if c, errCookie := r.Cookie(name); errCookie == nil {
- err = securecookie.DecodeMulti(name, c.Value, &session.Values,
- s.Codecs...)
- if err == nil {
- session.IsNew = false
- }
- }
- return session, err
-}
-
-// Save adds a single session to the response.
-func (s *CookieStore) Save(r *http.Request, w http.ResponseWriter,
- session *Session) error {
- encoded, err := securecookie.EncodeMulti(session.Name(), session.Values,
- s.Codecs...)
- if err != nil {
- return err
- }
- http.SetCookie(w, NewCookie(session.Name(), encoded, session.Options))
- return nil
-}
-
-// MaxAge sets the maximum age for the store and the underlying cookie
-// implementation. Individual sessions can be deleted by setting Options.MaxAge
-// = -1 for that session.
-func (s *CookieStore) MaxAge(age int) {
- s.Options.MaxAge = age
-
- // Set the maxAge for each securecookie instance.
- for _, codec := range s.Codecs {
- if sc, ok := codec.(*securecookie.SecureCookie); ok {
- sc.MaxAge(age)
- }
- }
-}
-
-// FilesystemStore ------------------------------------------------------------
-
-var fileMutex sync.RWMutex
-
-// NewFilesystemStore returns a new FilesystemStore.
-//
-// The path argument is the directory where sessions will be saved. If empty
-// it will use os.TempDir().
-//
-// See NewCookieStore() for a description of the other parameters.
-func NewFilesystemStore(path string, keyPairs ...[]byte) *FilesystemStore {
- if path == "" {
- path = os.TempDir()
- }
- fs := &FilesystemStore{
- Codecs: securecookie.CodecsFromPairs(keyPairs...),
- Options: &Options{
- Path: "/",
- MaxAge: 86400 * 30,
- },
- path: path,
- }
-
- fs.MaxAge(fs.Options.MaxAge)
- return fs
-}
-
-// FilesystemStore stores sessions in the filesystem.
-//
-// It also serves as a reference for custom stores.
-//
-// This store is still experimental and not well tested. Feedback is welcome.
-type FilesystemStore struct {
- Codecs []securecookie.Codec
- Options *Options // default configuration
- path string
-}
-
-// MaxLength restricts the maximum length of new sessions to l.
-// If l is 0 there is no limit to the size of a session, use with caution.
-// The default for a new FilesystemStore is 4096.
-func (s *FilesystemStore) MaxLength(l int) {
- for _, c := range s.Codecs {
- if codec, ok := c.(*securecookie.SecureCookie); ok {
- codec.MaxLength(l)
- }
- }
-}
-
-// Get returns a session for the given name after adding it to the registry.
-//
-// See CookieStore.Get().
-func (s *FilesystemStore) Get(r *http.Request, name string) (*Session, error) {
- return GetRegistry(r).Get(s, name)
-}
-
-// New returns a session for the given name without adding it to the registry.
-//
-// See CookieStore.New().
-func (s *FilesystemStore) New(r *http.Request, name string) (*Session, error) {
- session := NewSession(s, name)
- opts := *s.Options
- session.Options = &opts
- session.IsNew = true
- var err error
- if c, errCookie := r.Cookie(name); errCookie == nil {
- err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...)
- if err == nil {
- err = s.load(session)
- if err == nil {
- session.IsNew = false
- }
- }
- }
- return session, err
-}
-
-var base32RawStdEncoding = base32.StdEncoding.WithPadding(base32.NoPadding)
-
-// Save adds a single session to the response.
-//
-// If the Options.MaxAge of the session is <= 0 then the session file will be
-// deleted from the store path. With this process it enforces the properly
-// session cookie handling so no need to trust in the cookie management in the
-// web browser.
-func (s *FilesystemStore) Save(r *http.Request, w http.ResponseWriter,
- session *Session) error {
- // Delete if max-age is <= 0
- if session.Options.MaxAge <= 0 {
- if err := s.erase(session); err != nil && !os.IsNotExist(err) {
- return err
- }
- http.SetCookie(w, NewCookie(session.Name(), "", session.Options))
- return nil
- }
-
- if session.ID == "" {
- // Because the ID is used in the filename, encode it to
- // use alphanumeric characters only.
- session.ID = base32RawStdEncoding.EncodeToString(
- securecookie.GenerateRandomKey(32))
- }
- if err := s.save(session); err != nil {
- return err
- }
- encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
- s.Codecs...)
- if err != nil {
- return err
- }
- http.SetCookie(w, NewCookie(session.Name(), encoded, session.Options))
- return nil
-}
-
-// MaxAge sets the maximum age for the store and the underlying cookie
-// implementation. Individual sessions can be deleted by setting Options.MaxAge
-// = -1 for that session.
-func (s *FilesystemStore) MaxAge(age int) {
- s.Options.MaxAge = age
-
- // Set the maxAge for each securecookie instance.
- for _, codec := range s.Codecs {
- if sc, ok := codec.(*securecookie.SecureCookie); ok {
- sc.MaxAge(age)
- }
- }
-}
-
-// save writes encoded session.Values to a file.
-func (s *FilesystemStore) save(session *Session) error {
- encoded, err := securecookie.EncodeMulti(session.Name(), session.Values,
- s.Codecs...)
- if err != nil {
- return err
- }
- filename := filepath.Join(s.path, "session_"+session.ID)
- fileMutex.Lock()
- defer fileMutex.Unlock()
- return os.WriteFile(filename, []byte(encoded), 0600)
-}
-
-// load reads a file and decodes its content into session.Values.
-func (s *FilesystemStore) load(session *Session) error {
- filename := filepath.Join(s.path, "session_"+session.ID)
- fileMutex.RLock()
- defer fileMutex.RUnlock()
- fdata, err := os.ReadFile(filepath.Clean(filename))
- if err != nil {
- return err
- }
- if err = securecookie.DecodeMulti(session.Name(), string(fdata),
- &session.Values, s.Codecs...); err != nil {
- return err
- }
- return nil
-}
-
-// delete session file
-func (s *FilesystemStore) erase(session *Session) error {
- filename := filepath.Join(s.path, "session_"+session.ID)
-
- fileMutex.RLock()
- defer fileMutex.RUnlock()
-
- err := os.Remove(filename)
- return err
-}
diff --git a/vendor/github.com/gorilla/websocket/.gitignore b/vendor/github.com/gorilla/websocket/.gitignore
deleted file mode 100644
index cd3fcd1ef..000000000
--- a/vendor/github.com/gorilla/websocket/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-
-.idea/
-*.iml
diff --git a/vendor/github.com/gorilla/websocket/AUTHORS b/vendor/github.com/gorilla/websocket/AUTHORS
deleted file mode 100644
index 1931f4006..000000000
--- a/vendor/github.com/gorilla/websocket/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# This is the official list of Gorilla WebSocket authors for copyright
-# purposes.
-#
-# Please keep the list sorted.
-
-Gary Burd <gary@beagledreams.com>
-Google LLC (https://opensource.google.com/)
-Joachim Bauch <mail@joachim-bauch.de>
-
diff --git a/vendor/github.com/gorilla/websocket/LICENSE b/vendor/github.com/gorilla/websocket/LICENSE
deleted file mode 100644
index 9171c9722..000000000
--- a/vendor/github.com/gorilla/websocket/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
- Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md
deleted file mode 100644
index d33ed7fdd..000000000
--- a/vendor/github.com/gorilla/websocket/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Gorilla WebSocket
-
-[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
-[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket)
-
-Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
-[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
-
-
-### Documentation
-
-* [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc)
-* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
-* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
-* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
-* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
-
-### Status
-
-The Gorilla WebSocket package provides a complete and tested implementation of
-the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
-package API is stable.
-
-### Installation
-
- go get github.com/gorilla/websocket
-
-### Protocol Compliance
-
-The Gorilla WebSocket package passes the server tests in the [Autobahn Test
-Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn
-subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
-
diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go
deleted file mode 100644
index 04fdafee1..000000000
--- a/vendor/github.com/gorilla/websocket/client.go
+++ /dev/null
@@ -1,434 +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"
- "context"
- "crypto/tls"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "net/http/httptrace"
- "net/url"
- "strings"
- "time"
-)
-
-// ErrBadHandshake is returned when the server response to opening handshake is
-// invalid.
-var ErrBadHandshake = errors.New("websocket: bad handshake")
-
-var errInvalidCompression = errors.New("websocket: invalid compression negotiation")
-
-// NewClient creates a new client connection using the given net connection.
-// The URL u specifies the host and request URI. Use requestHeader to specify
-// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
-// (Cookie). Use the response.Header to get the selected subprotocol
-// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
-//
-// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
-// non-nil *http.Response so that callers can handle redirects, authentication,
-// etc.
-//
-// Deprecated: Use Dialer instead.
-func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
- d := Dialer{
- ReadBufferSize: readBufSize,
- WriteBufferSize: writeBufSize,
- NetDial: func(net, addr string) (net.Conn, error) {
- return netConn, nil
- },
- }
- return d.Dial(u.String(), requestHeader)
-}
-
-// A Dialer contains options for connecting to WebSocket server.
-//
-// It is safe to call Dialer's methods concurrently.
-type Dialer struct {
- // NetDial specifies the dial function for creating TCP connections. If
- // NetDial is nil, net.Dial is used.
- NetDial func(network, addr string) (net.Conn, error)
-
- // NetDialContext specifies the dial function for creating TCP connections. If
- // NetDialContext is nil, NetDial is used.
- NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)
-
- // NetDialTLSContext specifies the dial function for creating TLS/TCP connections. If
- // NetDialTLSContext is nil, NetDialContext is used.
- // If NetDialTLSContext is set, Dial assumes the TLS handshake is done there and
- // TLSClientConfig is ignored.
- NetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
-
- // Proxy specifies a function to return a proxy for a given
- // Request. If the function returns a non-nil error, the
- // request is aborted with the provided error.
- // If Proxy is nil or returns a nil *URL, no proxy is used.
- Proxy func(*http.Request) (*url.URL, error)
-
- // TLSClientConfig specifies the TLS configuration to use with tls.Client.
- // If nil, the default configuration is used.
- // If either NetDialTLS or NetDialTLSContext are set, Dial assumes the TLS handshake
- // is done there and TLSClientConfig is ignored.
- TLSClientConfig *tls.Config
-
- // HandshakeTimeout specifies the duration for the handshake to complete.
- HandshakeTimeout time.Duration
-
- // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer
- // size is zero, then a useful default size is used. The I/O buffer sizes
- // do not limit the size of the messages that can be sent or received.
- ReadBufferSize, WriteBufferSize int
-
- // WriteBufferPool is a pool of buffers for write operations. If the value
- // is not set, then write buffers are allocated to the connection for the
- // lifetime of the connection.
- //
- // A pool is most useful when the application has a modest volume of writes
- // across a large number of connections.
- //
- // Applications should use a single pool for each unique value of
- // WriteBufferSize.
- WriteBufferPool BufferPool
-
- // Subprotocols specifies the client's requested subprotocols.
- Subprotocols []string
-
- // EnableCompression specifies if the client should attempt to negotiate
- // per message compression (RFC 7692). Setting this value to true does not
- // guarantee that compression will be supported. Currently only "no context
- // takeover" modes are supported.
- EnableCompression bool
-
- // Jar specifies the cookie jar.
- // If Jar is nil, cookies are not sent in requests and ignored
- // in responses.
- Jar http.CookieJar
-}
-
-// Dial creates a new client connection by calling DialContext with a background context.
-func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
- return d.DialContext(context.Background(), urlStr, requestHeader)
-}
-
-var errMalformedURL = errors.New("malformed ws or wss URL")
-
-func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
- hostPort = u.Host
- hostNoPort = u.Host
- if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
- hostNoPort = hostNoPort[:i]
- } else {
- switch u.Scheme {
- case "wss":
- hostPort += ":443"
- case "https":
- hostPort += ":443"
- default:
- hostPort += ":80"
- }
- }
- return hostPort, hostNoPort
-}
-
-// DefaultDialer is a dialer with all fields set to the default values.
-var DefaultDialer = &Dialer{
- Proxy: http.ProxyFromEnvironment,
- HandshakeTimeout: 45 * time.Second,
-}
-
-// nilDialer is dialer to use when receiver is nil.
-var nilDialer = *DefaultDialer
-
-// DialContext 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
-// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
-//
-// The context will be used in the request and in the Dialer.
-//
-// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
-// non-nil *http.Response so that callers can handle redirects, authentication,
-// etcetera. The response body may not contain the entire response and does not
-// need to be closed by the application.
-func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
- if d == nil {
- d = &nilDialer
- }
-
- challengeKey, err := generateChallengeKey()
- if err != nil {
- return nil, nil, err
- }
-
- u, err := url.Parse(urlStr)
- if err != nil {
- return nil, nil, err
- }
-
- switch u.Scheme {
- case "ws":
- u.Scheme = "http"
- case "wss":
- u.Scheme = "https"
- default:
- return nil, nil, errMalformedURL
- }
-
- if u.User != nil {
- // User name and password are not allowed in websocket URIs.
- return nil, nil, errMalformedURL
- }
-
- req := &http.Request{
- Method: http.MethodGet,
- URL: u,
- Proto: "HTTP/1.1",
- ProtoMajor: 1,
- ProtoMinor: 1,
- Header: make(http.Header),
- Host: u.Host,
- }
- req = req.WithContext(ctx)
-
- // Set the cookies present in the cookie jar of the dialer
- if d.Jar != nil {
- for _, cookie := range d.Jar.Cookies(u) {
- req.AddCookie(cookie)
- }
- }
-
- // Set the request headers using the capitalization for names and values in
- // RFC examples. Although the capitalization shouldn't matter, there are
- // servers that depend on it. The Header.Set method is not used because the
- // method canonicalizes the header names.
- req.Header["Upgrade"] = []string{"websocket"}
- req.Header["Connection"] = []string{"Upgrade"}
- req.Header["Sec-WebSocket-Key"] = []string{challengeKey}
- req.Header["Sec-WebSocket-Version"] = []string{"13"}
- if len(d.Subprotocols) > 0 {
- req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")}
- }
- for k, vs := range requestHeader {
- switch {
- case k == "Host":
- if len(vs) > 0 {
- req.Host = vs[0]
- }
- case k == "Upgrade" ||
- k == "Connection" ||
- k == "Sec-Websocket-Key" ||
- k == "Sec-Websocket-Version" ||
- 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
- }
- }
-
- if d.EnableCompression {
- req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"}
- }
-
- if d.HandshakeTimeout != 0 {
- var cancel func()
- ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout)
- defer cancel()
- }
-
- // Get network dial function.
- var netDial func(network, add string) (net.Conn, error)
-
- switch u.Scheme {
- case "http":
- if d.NetDialContext != nil {
- netDial = func(network, addr string) (net.Conn, error) {
- return d.NetDialContext(ctx, network, addr)
- }
- } else if d.NetDial != nil {
- netDial = d.NetDial
- }
- case "https":
- if d.NetDialTLSContext != nil {
- netDial = func(network, addr string) (net.Conn, error) {
- return d.NetDialTLSContext(ctx, network, addr)
- }
- } else if d.NetDialContext != nil {
- netDial = func(network, addr string) (net.Conn, error) {
- return d.NetDialContext(ctx, network, addr)
- }
- } else if d.NetDial != nil {
- netDial = d.NetDial
- }
- default:
- return nil, nil, errMalformedURL
- }
-
- if netDial == nil {
- netDialer := &net.Dialer{}
- netDial = func(network, addr string) (net.Conn, error) {
- return netDialer.DialContext(ctx, network, addr)
- }
- }
-
- // If needed, wrap the dial function to set the connection deadline.
- if deadline, ok := ctx.Deadline(); ok {
- forwardDial := netDial
- netDial = func(network, addr string) (net.Conn, error) {
- c, err := forwardDial(network, addr)
- if err != nil {
- return nil, err
- }
- err = c.SetDeadline(deadline)
- if err != nil {
- c.Close()
- return nil, err
- }
- return c, nil
- }
- }
-
- // If needed, wrap the dial function to connect through a proxy.
- if d.Proxy != nil {
- proxyURL, err := d.Proxy(req)
- if err != nil {
- return nil, nil, err
- }
- if proxyURL != nil {
- dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))
- if err != nil {
- return nil, nil, err
- }
- netDial = dialer.Dial
- }
- }
-
- hostPort, hostNoPort := hostPortNoPort(u)
- trace := httptrace.ContextClientTrace(ctx)
- if trace != nil && trace.GetConn != nil {
- trace.GetConn(hostPort)
- }
-
- netConn, err := netDial("tcp", hostPort)
- if err != nil {
- return nil, nil, err
- }
- if trace != nil && trace.GotConn != nil {
- trace.GotConn(httptrace.GotConnInfo{
- Conn: netConn,
- })
- }
-
- defer func() {
- if netConn != nil {
- netConn.Close()
- }
- }()
-
- if u.Scheme == "https" && d.NetDialTLSContext == nil {
- // If NetDialTLSContext is set, assume that the TLS handshake has already been done
-
- cfg := cloneTLSConfig(d.TLSClientConfig)
- if cfg.ServerName == "" {
- cfg.ServerName = hostNoPort
- }
- tlsConn := tls.Client(netConn, cfg)
- netConn = tlsConn
-
- if trace != nil && trace.TLSHandshakeStart != nil {
- trace.TLSHandshakeStart()
- }
- err := doHandshake(ctx, tlsConn, cfg)
- if trace != nil && trace.TLSHandshakeDone != nil {
- trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
- }
-
- if err != nil {
- return nil, nil, err
- }
- }
-
- conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil)
-
- if err := req.Write(netConn); err != nil {
- return nil, nil, err
- }
-
- if trace != nil && trace.GotFirstResponseByte != nil {
- if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 {
- trace.GotFirstResponseByte()
- }
- }
-
- resp, err := http.ReadResponse(conn.br, req)
- if err != nil {
- if d.TLSClientConfig != nil {
- for _, proto := range d.TLSClientConfig.NextProtos {
- if proto != "http/1.1" {
- return nil, nil, fmt.Errorf(
- "websocket: protocol %q was given but is not supported;"+
- "sharing tls.Config with net/http Transport can cause this error: %w",
- proto, err,
- )
- }
- }
- }
- return nil, nil, err
- }
-
- if d.Jar != nil {
- if rc := resp.Cookies(); len(rc) > 0 {
- d.Jar.SetCookies(u, rc)
- }
- }
-
- if resp.StatusCode != 101 ||
- !tokenListContainsValue(resp.Header, "Upgrade", "websocket") ||
- !tokenListContainsValue(resp.Header, "Connection", "upgrade") ||
- resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
- // Before closing the network connection on return from this
- // function, slurp up some of the response to aid application
- // debugging.
- buf := make([]byte, 1024)
- n, _ := io.ReadFull(resp.Body, buf)
- resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
- return nil, resp, ErrBadHandshake
- }
-
- for _, ext := range parseExtensions(resp.Header) {
- if ext[""] != "permessage-deflate" {
- continue
- }
- _, snct := ext["server_no_context_takeover"]
- _, cnct := ext["client_no_context_takeover"]
- if !snct || !cnct {
- return nil, resp, errInvalidCompression
- }
- conn.newCompressionWriter = compressNoContextTakeover
- conn.newDecompressionReader = decompressNoContextTakeover
- break
- }
-
- resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
- conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
-
- netConn.SetDeadline(time.Time{})
- netConn = nil // to avoid close in defer.
- return conn, resp, nil
-}
-
-func cloneTLSConfig(cfg *tls.Config) *tls.Config {
- if cfg == nil {
- return &tls.Config{}
- }
- return cfg.Clone()
-}
diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go
deleted file mode 100644
index 813ffb1e8..000000000
--- a/vendor/github.com/gorilla/websocket/compression.go
+++ /dev/null
@@ -1,148 +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 (
- "compress/flate"
- "errors"
- "io"
- "strings"
- "sync"
-)
-
-const (
- minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6
- maxCompressionLevel = flate.BestCompression
- defaultCompressionLevel = 1
-)
-
-var (
- flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool
- flateReaderPool = sync.Pool{New: func() interface{} {
- return flate.NewReader(nil)
- }}
-)
-
-func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
- const tail =
- // Add four bytes as specified in RFC
- "\x00\x00\xff\xff" +
- // Add final block to squelch unexpected EOF error from flate reader.
- "\x01\x00\x00\xff\xff"
-
- fr, _ := flateReaderPool.Get().(io.ReadCloser)
- fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)
- return &flateReadWrapper{fr}
-}
-
-func isValidCompressionLevel(level int) bool {
- return minCompressionLevel <= level && level <= maxCompressionLevel
-}
-
-func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {
- p := &flateWriterPools[level-minCompressionLevel]
- tw := &truncWriter{w: w}
- fw, _ := p.Get().(*flate.Writer)
- if fw == nil {
- fw, _ = flate.NewWriter(tw, level)
- } else {
- fw.Reset(tw)
- }
- return &flateWriteWrapper{fw: fw, tw: tw, p: p}
-}
-
-// truncWriter is an io.Writer that writes all but the last four bytes of the
-// stream to another io.Writer.
-type truncWriter struct {
- w io.WriteCloser
- n int
- p [4]byte
-}
-
-func (w *truncWriter) Write(p []byte) (int, error) {
- n := 0
-
- // fill buffer first for simplicity.
- if w.n < len(w.p) {
- n = copy(w.p[w.n:], p)
- p = p[n:]
- w.n += n
- if len(p) == 0 {
- return n, nil
- }
- }
-
- m := len(p)
- if m > len(w.p) {
- m = len(w.p)
- }
-
- if nn, err := w.w.Write(w.p[:m]); err != nil {
- return n + nn, err
- }
-
- copy(w.p[:], w.p[m:])
- copy(w.p[len(w.p)-m:], p[len(p)-m:])
- nn, err := w.w.Write(p[:len(p)-m])
- return n + nn, err
-}
-
-type flateWriteWrapper struct {
- fw *flate.Writer
- tw *truncWriter
- p *sync.Pool
-}
-
-func (w *flateWriteWrapper) Write(p []byte) (int, error) {
- if w.fw == nil {
- return 0, errWriteClosed
- }
- return w.fw.Write(p)
-}
-
-func (w *flateWriteWrapper) Close() error {
- if w.fw == nil {
- return errWriteClosed
- }
- err1 := w.fw.Flush()
- w.p.Put(w.fw)
- w.fw = nil
- if w.tw.p != [4]byte{0, 0, 0xff, 0xff} {
- return errors.New("websocket: internal error, unexpected bytes at end of flate stream")
- }
- err2 := w.tw.w.Close()
- if err1 != nil {
- return err1
- }
- return err2
-}
-
-type flateReadWrapper struct {
- fr io.ReadCloser
-}
-
-func (r *flateReadWrapper) Read(p []byte) (int, error) {
- if r.fr == nil {
- return 0, io.ErrClosedPipe
- }
- n, err := r.fr.Read(p)
- if err == io.EOF {
- // Preemptively place the reader back in the pool. This helps with
- // scenarios where the application does not call NextReader() soon after
- // this final read.
- r.Close()
- }
- return n, err
-}
-
-func (r *flateReadWrapper) Close() error {
- if r.fr == nil {
- return io.ErrClosedPipe
- }
- err := r.fr.Close()
- flateReaderPool.Put(r.fr)
- r.fr = nil
- return err
-}
diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go
deleted file mode 100644
index 5161ef81f..000000000
--- a/vendor/github.com/gorilla/websocket/conn.go
+++ /dev/null
@@ -1,1238 +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"
- "encoding/binary"
- "errors"
- "io"
- "io/ioutil"
- "math/rand"
- "net"
- "strconv"
- "strings"
- "sync"
- "time"
- "unicode/utf8"
-)
-
-const (
- // Frame header byte 0 bits from Section 5.2 of RFC 6455
- finalBit = 1 << 7
- rsv1Bit = 1 << 6
- rsv2Bit = 1 << 5
- rsv3Bit = 1 << 4
-
- // Frame header byte 1 bits from Section 5.2 of RFC 6455
- maskBit = 1 << 7
-
- maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask
- maxControlFramePayloadSize = 125
-
- writeWait = time.Second
-
- defaultReadBufferSize = 4096
- defaultWriteBufferSize = 4096
-
- continuationFrame = 0
- noFrame = -1
-)
-
-// Close codes defined in RFC 6455, section 11.7.
-const (
- CloseNormalClosure = 1000
- CloseGoingAway = 1001
- CloseProtocolError = 1002
- CloseUnsupportedData = 1003
- CloseNoStatusReceived = 1005
- CloseAbnormalClosure = 1006
- CloseInvalidFramePayloadData = 1007
- ClosePolicyViolation = 1008
- CloseMessageTooBig = 1009
- CloseMandatoryExtension = 1010
- CloseInternalServerErr = 1011
- CloseServiceRestart = 1012
- CloseTryAgainLater = 1013
- CloseTLSHandshake = 1015
-)
-
-// The message types are defined in RFC 6455, section 11.8.
-const (
- // TextMessage denotes a text data message. The text message payload is
- // interpreted as UTF-8 encoded text data.
- TextMessage = 1
-
- // BinaryMessage denotes a binary data message.
- BinaryMessage = 2
-
- // CloseMessage denotes a close control message. The optional message
- // payload contains a numeric code and text. Use the FormatCloseMessage
- // function to format a close message payload.
- CloseMessage = 8
-
- // PingMessage denotes a ping control message. The optional message payload
- // is UTF-8 encoded text.
- PingMessage = 9
-
- // PongMessage denotes a pong control message. The optional message payload
- // is UTF-8 encoded text.
- PongMessage = 10
-)
-
-// ErrCloseSent is returned when the application writes a message to the
-// connection after sending a close message.
-var ErrCloseSent = errors.New("websocket: close sent")
-
-// ErrReadLimit is returned when reading a message that is larger than the
-// read limit set for the connection.
-var ErrReadLimit = errors.New("websocket: read limit exceeded")
-
-// netError satisfies the net Error interface.
-type netError struct {
- msg string
- temporary bool
- timeout bool
-}
-
-func (e *netError) Error() string { return e.msg }
-func (e *netError) Temporary() bool { return e.temporary }
-func (e *netError) Timeout() bool { return e.timeout }
-
-// CloseError represents a close message.
-type CloseError struct {
- // Code is defined in RFC 6455, section 11.7.
- Code int
-
- // Text is the optional text payload.
- Text string
-}
-
-func (e *CloseError) Error() string {
- s := []byte("websocket: close ")
- s = strconv.AppendInt(s, int64(e.Code), 10)
- switch e.Code {
- case CloseNormalClosure:
- s = append(s, " (normal)"...)
- case CloseGoingAway:
- s = append(s, " (going away)"...)
- case CloseProtocolError:
- s = append(s, " (protocol error)"...)
- case CloseUnsupportedData:
- s = append(s, " (unsupported data)"...)
- case CloseNoStatusReceived:
- s = append(s, " (no status)"...)
- case CloseAbnormalClosure:
- s = append(s, " (abnormal closure)"...)
- case CloseInvalidFramePayloadData:
- s = append(s, " (invalid payload data)"...)
- case ClosePolicyViolation:
- s = append(s, " (policy violation)"...)
- case CloseMessageTooBig:
- s = append(s, " (message too big)"...)
- case CloseMandatoryExtension:
- s = append(s, " (mandatory extension missing)"...)
- case CloseInternalServerErr:
- s = append(s, " (internal server error)"...)
- case CloseTLSHandshake:
- s = append(s, " (TLS handshake error)"...)
- }
- if e.Text != "" {
- s = append(s, ": "...)
- s = append(s, e.Text...)
- }
- return string(s)
-}
-
-// IsCloseError returns boolean indicating whether the error is a *CloseError
-// with one of the specified codes.
-func IsCloseError(err error, codes ...int) bool {
- if e, ok := err.(*CloseError); ok {
- for _, code := range codes {
- if e.Code == code {
- return true
- }
- }
- }
- return false
-}
-
-// IsUnexpectedCloseError returns boolean indicating whether the error is a
-// *CloseError with a code not in the list of expected codes.
-func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
- if e, ok := err.(*CloseError); ok {
- for _, code := range expectedCodes {
- if e.Code == code {
- return false
- }
- }
- return true
- }
- return false
-}
-
-var (
- errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
- errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
- errBadWriteOpCode = errors.New("websocket: bad write message type")
- errWriteClosed = errors.New("websocket: write closed")
- errInvalidControlFrame = errors.New("websocket: invalid control frame")
-)
-
-func newMaskKey() [4]byte {
- n := rand.Uint32()
- return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
-}
-
-func hideTempErr(err error) error {
- if e, ok := err.(net.Error); ok && e.Temporary() {
- err = &netError{msg: e.Error(), timeout: e.Timeout()}
- }
- return err
-}
-
-func isControl(frameType int) bool {
- return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
-}
-
-func isData(frameType int) bool {
- return frameType == TextMessage || frameType == BinaryMessage
-}
-
-var validReceivedCloseCodes = map[int]bool{
- // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
-
- CloseNormalClosure: true,
- CloseGoingAway: true,
- CloseProtocolError: true,
- CloseUnsupportedData: true,
- CloseNoStatusReceived: false,
- CloseAbnormalClosure: false,
- CloseInvalidFramePayloadData: true,
- ClosePolicyViolation: true,
- CloseMessageTooBig: true,
- CloseMandatoryExtension: true,
- CloseInternalServerErr: true,
- CloseServiceRestart: true,
- CloseTryAgainLater: true,
- CloseTLSHandshake: false,
-}
-
-func isValidReceivedCloseCode(code int) bool {
- return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
-}
-
-// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this
-// interface. The type of the value stored in a pool is not specified.
-type BufferPool interface {
- // Get gets a value from the pool or returns nil if the pool is empty.
- Get() interface{}
- // Put adds a value to the pool.
- Put(interface{})
-}
-
-// writePoolData is the type added to the write buffer pool. This wrapper is
-// used to prevent applications from peeking at and depending on the values
-// added to the pool.
-type writePoolData struct{ buf []byte }
-
-// The Conn type represents a WebSocket connection.
-type Conn struct {
- conn net.Conn
- isServer bool
- subprotocol string
-
- // Write fields
- mu chan struct{} // used as mutex to protect write to conn
- writeBuf []byte // frame is constructed in this buffer.
- writePool BufferPool
- writeBufSize int
- writeDeadline time.Time
- writer io.WriteCloser // the current writer returned to the application
- isWriting bool // for best-effort concurrent write detection
-
- writeErrMu sync.Mutex
- writeErr error
-
- enableWriteCompression bool
- compressionLevel int
- newCompressionWriter func(io.WriteCloser, int) io.WriteCloser
-
- // Read fields
- reader io.ReadCloser // the current reader returned to the application
- readErr error
- br *bufio.Reader
- // bytes remaining in current frame.
- // set setReadRemaining to safely update this value and prevent overflow
- readRemaining int64
- readFinal bool // true the current message has more frames.
- readLength int64 // Message size.
- readLimit int64 // Maximum message size.
- readMaskPos int
- readMaskKey [4]byte
- handlePong func(string) error
- handlePing func(string) error
- handleClose func(int, string) error
- readErrCount int
- messageReader *messageReader // the current low-level reader
-
- readDecompress bool // whether last read frame had RSV1 set
- newDecompressionReader func(io.Reader) io.ReadCloser
-}
-
-func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn {
-
- if br == nil {
- if readBufferSize == 0 {
- readBufferSize = defaultReadBufferSize
- } else if readBufferSize < maxControlFramePayloadSize {
- // must be large enough for control frame
- readBufferSize = maxControlFramePayloadSize
- }
- br = bufio.NewReaderSize(conn, readBufferSize)
- }
-
- if writeBufferSize <= 0 {
- writeBufferSize = defaultWriteBufferSize
- }
- writeBufferSize += maxFrameHeaderSize
-
- if writeBuf == nil && writeBufferPool == nil {
- writeBuf = make([]byte, writeBufferSize)
- }
-
- mu := make(chan struct{}, 1)
- mu <- struct{}{}
- c := &Conn{
- isServer: isServer,
- br: br,
- conn: conn,
- mu: mu,
- readFinal: true,
- writeBuf: writeBuf,
- writePool: writeBufferPool,
- writeBufSize: writeBufferSize,
- enableWriteCompression: true,
- compressionLevel: defaultCompressionLevel,
- }
- c.SetCloseHandler(nil)
- c.SetPingHandler(nil)
- c.SetPongHandler(nil)
- return c
-}
-
-// setReadRemaining tracks the number of bytes remaining on the connection. If n
-// overflows, an ErrReadLimit is returned.
-func (c *Conn) setReadRemaining(n int64) error {
- if n < 0 {
- return ErrReadLimit
- }
-
- c.readRemaining = n
- return nil
-}
-
-// Subprotocol returns the negotiated protocol for the connection.
-func (c *Conn) Subprotocol() string {
- return c.subprotocol
-}
-
-// Close closes the underlying network connection without sending or waiting
-// for a close message.
-func (c *Conn) Close() error {
- return c.conn.Close()
-}
-
-// LocalAddr returns the local network address.
-func (c *Conn) LocalAddr() net.Addr {
- return c.conn.LocalAddr()
-}
-
-// RemoteAddr returns the remote network address.
-func (c *Conn) RemoteAddr() net.Addr {
- return c.conn.RemoteAddr()
-}
-
-// Write methods
-
-func (c *Conn) writeFatal(err error) error {
- err = hideTempErr(err)
- c.writeErrMu.Lock()
- if c.writeErr == nil {
- c.writeErr = err
- }
- c.writeErrMu.Unlock()
- return err
-}
-
-func (c *Conn) read(n int) ([]byte, error) {
- p, err := c.br.Peek(n)
- if err == io.EOF {
- err = errUnexpectedEOF
- }
- c.br.Discard(len(p))
- return p, err
-}
-
-func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {
- <-c.mu
- defer func() { c.mu <- struct{}{} }()
-
- c.writeErrMu.Lock()
- err := c.writeErr
- c.writeErrMu.Unlock()
- if err != nil {
- return err
- }
-
- c.conn.SetWriteDeadline(deadline)
- 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)
- }
- return nil
-}
-
-func (c *Conn) writeBufs(bufs ...[]byte) error {
- b := net.Buffers(bufs)
- _, err := b.WriteTo(c.conn)
- return err
-}
-
-// WriteControl writes a control message with the given deadline. The allowed
-// message types are CloseMessage, PingMessage and PongMessage.
-func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
- if !isControl(messageType) {
- return errBadWriteOpCode
- }
- if len(data) > maxControlFramePayloadSize {
- return errInvalidControlFrame
- }
-
- b0 := byte(messageType) | finalBit
- b1 := byte(len(data))
- if !c.isServer {
- b1 |= maskBit
- }
-
- buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
- buf = append(buf, b0, b1)
-
- if c.isServer {
- buf = append(buf, data...)
- } else {
- key := newMaskKey()
- buf = append(buf, key[:]...)
- buf = append(buf, data...)
- maskBytes(key, 0, buf[6:])
- }
-
- d := 1000 * time.Hour
- if !deadline.IsZero() {
- d = deadline.Sub(time.Now())
- if d < 0 {
- return errWriteTimeout
- }
- }
-
- timer := time.NewTimer(d)
- select {
- case <-c.mu:
- timer.Stop()
- case <-timer.C:
- return errWriteTimeout
- }
- defer func() { c.mu <- struct{}{} }()
-
- c.writeErrMu.Lock()
- err := c.writeErr
- c.writeErrMu.Unlock()
- if err != nil {
- return err
- }
-
- c.conn.SetWriteDeadline(deadline)
- _, err = c.conn.Write(buf)
- if err != nil {
- return c.writeFatal(err)
- }
- if messageType == CloseMessage {
- c.writeFatal(ErrCloseSent)
- }
- return err
-}
-
-// beginMessage prepares a connection and message writer for a new message.
-func (c *Conn) beginMessage(mw *messageWriter, messageType int) error {
- // Close previous writer if not already closed by the application. It's
- // probably better to return an error in this situation, but we cannot
- // change this without breaking existing applications.
- if c.writer != nil {
- c.writer.Close()
- c.writer = nil
- }
-
- if !isControl(messageType) && !isData(messageType) {
- return errBadWriteOpCode
- }
-
- c.writeErrMu.Lock()
- err := c.writeErr
- c.writeErrMu.Unlock()
- if err != nil {
- return err
- }
-
- mw.c = c
- mw.frameType = messageType
- mw.pos = maxFrameHeaderSize
-
- if c.writeBuf == nil {
- wpd, ok := c.writePool.Get().(writePoolData)
- if ok {
- c.writeBuf = wpd.buf
- } else {
- c.writeBuf = make([]byte, c.writeBufSize)
- }
- }
- return nil
-}
-
-// NextWriter returns a writer for the next message to send. The writer's Close
-// method flushes the complete message to the network.
-//
-// There can be at most one open writer on a connection. NextWriter closes the
-// previous writer if the application has not already done so.
-//
-// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and
-// PongMessage) are supported.
-func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
- var mw messageWriter
- if err := c.beginMessage(&mw, messageType); err != nil {
- return nil, err
- }
- c.writer = &mw
- if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {
- w := c.newCompressionWriter(c.writer, c.compressionLevel)
- mw.compress = true
- c.writer = w
- }
- return c.writer, nil
-}
-
-type messageWriter struct {
- c *Conn
- compress bool // whether next call to flushFrame should set RSV1
- pos int // end of data in writeBuf.
- frameType int // type of the current frame.
- err error
-}
-
-func (w *messageWriter) endMessage(err error) error {
- if w.err != nil {
- return err
- }
- c := w.c
- w.err = err
- c.writer = nil
- if c.writePool != nil {
- c.writePool.Put(writePoolData{buf: c.writeBuf})
- c.writeBuf = nil
- }
- return err
-}
-
-// flushFrame writes buffered data and extra as a frame to the network. The
-// final argument indicates that this is the last frame in the message.
-func (w *messageWriter) flushFrame(final bool, extra []byte) error {
- c := w.c
- length := w.pos - maxFrameHeaderSize + len(extra)
-
- // Check for invalid control frames.
- if isControl(w.frameType) &&
- (!final || length > maxControlFramePayloadSize) {
- return w.endMessage(errInvalidControlFrame)
- }
-
- b0 := byte(w.frameType)
- if final {
- b0 |= finalBit
- }
- if w.compress {
- b0 |= rsv1Bit
- }
- w.compress = false
-
- b1 := byte(0)
- if !c.isServer {
- b1 |= maskBit
- }
-
- // Assume that the frame starts at beginning of c.writeBuf.
- framePos := 0
- if c.isServer {
- // Adjust up if mask not included in the header.
- framePos = 4
- }
-
- switch {
- case length >= 65536:
- c.writeBuf[framePos] = b0
- c.writeBuf[framePos+1] = b1 | 127
- binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
- case length > 125:
- framePos += 6
- c.writeBuf[framePos] = b0
- c.writeBuf[framePos+1] = b1 | 126
- binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
- default:
- framePos += 8
- c.writeBuf[framePos] = b0
- c.writeBuf[framePos+1] = b1 | byte(length)
- }
-
- if !c.isServer {
- key := newMaskKey()
- copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
- maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])
- if len(extra) > 0 {
- return w.endMessage(c.writeFatal(errors.New("websocket: internal error, extra used in client mode")))
- }
- }
-
- // Write the buffers to the connection with best-effort detection of
- // concurrent writes. See the concurrency section in the package
- // documentation for more info.
-
- if c.isWriting {
- panic("concurrent write to websocket connection")
- }
- c.isWriting = true
-
- err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)
-
- if !c.isWriting {
- panic("concurrent write to websocket connection")
- }
- c.isWriting = false
-
- if err != nil {
- return w.endMessage(err)
- }
-
- if final {
- w.endMessage(errWriteClosed)
- return nil
- }
-
- // Setup for next frame.
- w.pos = maxFrameHeaderSize
- w.frameType = continuationFrame
- return nil
-}
-
-func (w *messageWriter) ncopy(max int) (int, error) {
- n := len(w.c.writeBuf) - w.pos
- if n <= 0 {
- if err := w.flushFrame(false, nil); err != nil {
- return 0, err
- }
- n = len(w.c.writeBuf) - w.pos
- }
- if n > max {
- n = max
- }
- return n, nil
-}
-
-func (w *messageWriter) Write(p []byte) (int, error) {
- if w.err != nil {
- return 0, w.err
- }
-
- if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
- // Don't buffer large messages.
- err := w.flushFrame(false, p)
- if err != nil {
- return 0, err
- }
- return len(p), nil
- }
-
- nn := len(p)
- for len(p) > 0 {
- n, err := w.ncopy(len(p))
- if err != nil {
- return 0, err
- }
- copy(w.c.writeBuf[w.pos:], p[:n])
- w.pos += n
- p = p[n:]
- }
- return nn, nil
-}
-
-func (w *messageWriter) WriteString(p string) (int, error) {
- if w.err != nil {
- return 0, w.err
- }
-
- nn := len(p)
- for len(p) > 0 {
- n, err := w.ncopy(len(p))
- if err != nil {
- return 0, err
- }
- copy(w.c.writeBuf[w.pos:], p[:n])
- w.pos += n
- p = p[n:]
- }
- return nn, nil
-}
-
-func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
- if w.err != nil {
- return 0, w.err
- }
- for {
- if w.pos == len(w.c.writeBuf) {
- err = w.flushFrame(false, nil)
- if err != nil {
- break
- }
- }
- var n int
- n, err = r.Read(w.c.writeBuf[w.pos:])
- w.pos += n
- nn += int64(n)
- if err != nil {
- if err == io.EOF {
- err = nil
- }
- break
- }
- }
- return nn, err
-}
-
-func (w *messageWriter) Close() error {
- if w.err != nil {
- return w.err
- }
- return w.flushFrame(true, nil)
-}
-
-// WritePreparedMessage writes prepared message into connection.
-func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {
- frameType, frameData, err := pm.frame(prepareKey{
- isServer: c.isServer,
- compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),
- compressionLevel: c.compressionLevel,
- })
- if err != nil {
- return err
- }
- if c.isWriting {
- panic("concurrent write to websocket connection")
- }
- c.isWriting = true
- err = c.write(frameType, c.writeDeadline, frameData, nil)
- if !c.isWriting {
- panic("concurrent write to websocket connection")
- }
- c.isWriting = false
- return err
-}
-
-// WriteMessage is a helper method for getting a writer using NextWriter,
-// writing the message and closing the writer.
-func (c *Conn) WriteMessage(messageType int, data []byte) error {
-
- if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {
- // Fast path with no allocations and single frame.
-
- var mw messageWriter
- if err := c.beginMessage(&mw, messageType); err != nil {
- return err
- }
- n := copy(c.writeBuf[mw.pos:], data)
- mw.pos += n
- data = data[n:]
- return mw.flushFrame(true, data)
- }
-
- w, err := c.NextWriter(messageType)
- if err != nil {
- return err
- }
- if _, err = w.Write(data); err != nil {
- return err
- }
- return w.Close()
-}
-
-// SetWriteDeadline sets the write deadline on the underlying network
-// connection. After a write has timed out, the websocket state is corrupt and
-// all future writes will return an error. A zero value for t means writes will
-// not time out.
-func (c *Conn) SetWriteDeadline(t time.Time) error {
- c.writeDeadline = t
- return nil
-}
-
-// Read methods
-
-func (c *Conn) advanceFrame() (int, error) {
- // 1. Skip remainder of previous frame.
-
- if c.readRemaining > 0 {
- if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
- return noFrame, err
- }
- }
-
- // 2. Read and parse first two bytes of frame header.
- // To aid debugging, collect and report all errors in the first two bytes
- // of the header.
-
- var errors []string
-
- p, err := c.read(2)
- if err != nil {
- return noFrame, err
- }
-
- frameType := int(p[0] & 0xf)
- final := p[0]&finalBit != 0
- rsv1 := p[0]&rsv1Bit != 0
- rsv2 := p[0]&rsv2Bit != 0
- rsv3 := p[0]&rsv3Bit != 0
- mask := p[1]&maskBit != 0
- c.setReadRemaining(int64(p[1] & 0x7f))
-
- c.readDecompress = false
- if rsv1 {
- if c.newDecompressionReader != nil {
- c.readDecompress = true
- } else {
- errors = append(errors, "RSV1 set")
- }
- }
-
- if rsv2 {
- errors = append(errors, "RSV2 set")
- }
-
- if rsv3 {
- errors = append(errors, "RSV3 set")
- }
-
- switch frameType {
- case CloseMessage, PingMessage, PongMessage:
- if c.readRemaining > maxControlFramePayloadSize {
- errors = append(errors, "len > 125 for control")
- }
- if !final {
- errors = append(errors, "FIN not set on control")
- }
- case TextMessage, BinaryMessage:
- if !c.readFinal {
- errors = append(errors, "data before FIN")
- }
- c.readFinal = final
- case continuationFrame:
- if c.readFinal {
- errors = append(errors, "continuation after FIN")
- }
- c.readFinal = final
- default:
- errors = append(errors, "bad opcode "+strconv.Itoa(frameType))
- }
-
- if mask != c.isServer {
- errors = append(errors, "bad MASK")
- }
-
- if len(errors) > 0 {
- return noFrame, c.handleProtocolError(strings.Join(errors, ", "))
- }
-
- // 3. Read and parse frame length as per
- // https://tools.ietf.org/html/rfc6455#section-5.2
- //
- // The length of the "Payload data", in bytes: if 0-125, that is the payload
- // length.
- // - If 126, the following 2 bytes interpreted as a 16-bit unsigned
- // integer are the payload length.
- // - If 127, the following 8 bytes interpreted as
- // a 64-bit unsigned integer (the most significant bit MUST be 0) are the
- // payload length. Multibyte length quantities are expressed in network byte
- // order.
-
- switch c.readRemaining {
- case 126:
- p, err := c.read(2)
- if err != nil {
- return noFrame, err
- }
-
- if err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil {
- return noFrame, err
- }
- case 127:
- p, err := c.read(8)
- if err != nil {
- return noFrame, err
- }
-
- if err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil {
- return noFrame, err
- }
- }
-
- // 4. Handle frame masking.
-
- if mask {
- c.readMaskPos = 0
- p, err := c.read(len(c.readMaskKey))
- if err != nil {
- return noFrame, err
- }
- copy(c.readMaskKey[:], p)
- }
-
- // 5. For text and binary messages, enforce read limit and return.
-
- if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
-
- c.readLength += c.readRemaining
- // Don't allow readLength to overflow in the presence of a large readRemaining
- // counter.
- if c.readLength < 0 {
- return noFrame, ErrReadLimit
- }
-
- if c.readLimit > 0 && c.readLength > c.readLimit {
- c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
- return noFrame, ErrReadLimit
- }
-
- return frameType, nil
- }
-
- // 6. Read control frame payload.
-
- var payload []byte
- if c.readRemaining > 0 {
- payload, err = c.read(int(c.readRemaining))
- c.setReadRemaining(0)
- if err != nil {
- return noFrame, err
- }
- if c.isServer {
- maskBytes(c.readMaskKey, 0, payload)
- }
- }
-
- // 7. Process control frame payload.
-
- switch frameType {
- case PongMessage:
- if err := c.handlePong(string(payload)); err != nil {
- return noFrame, err
- }
- case PingMessage:
- if err := c.handlePing(string(payload)); err != nil {
- return noFrame, err
- }
- case CloseMessage:
- closeCode := CloseNoStatusReceived
- closeText := ""
- if len(payload) >= 2 {
- closeCode = int(binary.BigEndian.Uint16(payload))
- if !isValidReceivedCloseCode(closeCode) {
- return noFrame, c.handleProtocolError("bad close code " + strconv.Itoa(closeCode))
- }
- closeText = string(payload[2:])
- if !utf8.ValidString(closeText) {
- return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
- }
- }
- if err := c.handleClose(closeCode, closeText); err != nil {
- return noFrame, err
- }
- return noFrame, &CloseError{Code: closeCode, Text: closeText}
- }
-
- return frameType, nil
-}
-
-func (c *Conn) handleProtocolError(message string) error {
- data := FormatCloseMessage(CloseProtocolError, message)
- if len(data) > maxControlFramePayloadSize {
- data = data[:maxControlFramePayloadSize]
- }
- c.WriteControl(CloseMessage, data, time.Now().Add(writeWait))
- return errors.New("websocket: " + message)
-}
-
-// NextReader returns the next data message received from the peer. The
-// returned messageType is either TextMessage or BinaryMessage.
-//
-// There can be at most one open reader on a connection. NextReader discards
-// the previous message if the application has not already consumed it.
-//
-// Applications must break out of the application's read loop when this method
-// returns a non-nil error value. Errors returned from this method are
-// permanent. Once this method returns a non-nil error, all subsequent calls to
-// this method return the same error.
-func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
- // Close previous reader, only relevant for decompression.
- if c.reader != nil {
- c.reader.Close()
- c.reader = nil
- }
-
- c.messageReader = nil
- c.readLength = 0
-
- for c.readErr == nil {
- frameType, err := c.advanceFrame()
- if err != nil {
- c.readErr = hideTempErr(err)
- break
- }
-
- if frameType == TextMessage || frameType == BinaryMessage {
- c.messageReader = &messageReader{c}
- c.reader = c.messageReader
- if c.readDecompress {
- c.reader = c.newDecompressionReader(c.reader)
- }
- return frameType, c.reader, nil
- }
- }
-
- // Applications that do handle the error returned from this method spin in
- // tight loop on connection failure. To help application developers detect
- // this error, panic on repeated reads to the failed connection.
- c.readErrCount++
- if c.readErrCount >= 1000 {
- panic("repeated read on failed websocket connection")
- }
-
- return noFrame, nil, c.readErr
-}
-
-type messageReader struct{ c *Conn }
-
-func (r *messageReader) Read(b []byte) (int, error) {
- c := r.c
- if c.messageReader != r {
- return 0, io.EOF
- }
-
- for c.readErr == nil {
-
- if c.readRemaining > 0 {
- if int64(len(b)) > c.readRemaining {
- b = b[:c.readRemaining]
- }
- n, err := c.br.Read(b)
- c.readErr = hideTempErr(err)
- if c.isServer {
- c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
- }
- rem := c.readRemaining
- rem -= int64(n)
- c.setReadRemaining(rem)
- if c.readRemaining > 0 && c.readErr == io.EOF {
- c.readErr = errUnexpectedEOF
- }
- return n, c.readErr
- }
-
- if c.readFinal {
- c.messageReader = nil
- return 0, io.EOF
- }
-
- frameType, err := c.advanceFrame()
- switch {
- case err != nil:
- c.readErr = hideTempErr(err)
- case frameType == TextMessage || frameType == BinaryMessage:
- c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
- }
- }
-
- err := c.readErr
- if err == io.EOF && c.messageReader == r {
- err = errUnexpectedEOF
- }
- return 0, err
-}
-
-func (r *messageReader) Close() error {
- return nil
-}
-
-// ReadMessage is a helper method for getting a reader using NextReader and
-// reading from that reader to a buffer.
-func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
- var r io.Reader
- messageType, r, err = c.NextReader()
- if err != nil {
- return messageType, nil, err
- }
- p, err = ioutil.ReadAll(r)
- return messageType, p, err
-}
-
-// SetReadDeadline sets the read deadline on the underlying network connection.
-// After a read has timed out, the websocket connection state is corrupt and
-// all future reads will return an error. A zero value for t means reads will
-// not time out.
-func (c *Conn) SetReadDeadline(t time.Time) error {
- return c.conn.SetReadDeadline(t)
-}
-
-// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a
-// message exceeds the limit, the connection sends a close message to the peer
-// and returns ErrReadLimit to the application.
-func (c *Conn) SetReadLimit(limit int64) {
- c.readLimit = limit
-}
-
-// CloseHandler returns the current close handler
-func (c *Conn) CloseHandler() func(code int, text string) error {
- return c.handleClose
-}
-
-// SetCloseHandler sets the handler for close messages received from the peer.
-// The code argument to h is the received close code or CloseNoStatusReceived
-// if the close message is empty. The default close handler sends a close
-// message back to the peer.
-//
-// The handler function is called from the NextReader, ReadMessage and message
-// reader Read methods. The application must read the connection to process
-// close messages as described in the section on Control Messages above.
-//
-// The connection read methods return a CloseError when a close message is
-// received. Most applications should handle close messages as part of their
-// normal error handling. Applications should only set a close handler when the
-// application must perform some action before sending a close message back to
-// the peer.
-func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
- if h == nil {
- h = func(code int, text string) error {
- message := FormatCloseMessage(code, "")
- c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
- return nil
- }
- }
- c.handleClose = h
-}
-
-// PingHandler returns the current ping handler
-func (c *Conn) PingHandler() func(appData string) error {
- return c.handlePing
-}
-
-// SetPingHandler sets the handler for ping messages received from the peer.
-// The appData argument to h is the PING message application data. The default
-// ping handler sends a pong to the peer.
-//
-// The handler function is called from the NextReader, ReadMessage and message
-// reader Read methods. The application must read the connection to process
-// ping messages as described in the section on Control Messages above.
-func (c *Conn) SetPingHandler(h func(appData string) error) {
- if h == nil {
- h = func(message string) error {
- err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
- if err == ErrCloseSent {
- return nil
- } else if e, ok := err.(net.Error); ok && e.Temporary() {
- return nil
- }
- return err
- }
- }
- c.handlePing = h
-}
-
-// PongHandler returns the current pong handler
-func (c *Conn) PongHandler() func(appData string) error {
- return c.handlePong
-}
-
-// SetPongHandler sets the handler for pong messages received from the peer.
-// The appData argument to h is the PONG message application data. The default
-// pong handler does nothing.
-//
-// The handler function is called from the NextReader, ReadMessage and message
-// reader Read methods. The application must read the connection to process
-// pong messages as described in the section on Control Messages above.
-func (c *Conn) SetPongHandler(h func(appData string) error) {
- if h == nil {
- h = func(string) error { return nil }
- }
- c.handlePong = h
-}
-
-// NetConn returns the underlying connection that is wrapped by c.
-// Note that writing to or reading from this connection directly will corrupt the
-// WebSocket connection.
-func (c *Conn) NetConn() net.Conn {
- return c.conn
-}
-
-// UnderlyingConn returns the internal net.Conn. This can be used to further
-// modifications to connection specific flags.
-// Deprecated: Use the NetConn method.
-func (c *Conn) UnderlyingConn() net.Conn {
- return c.conn
-}
-
-// EnableWriteCompression enables and disables write compression of
-// subsequent text and binary messages. This function is a noop if
-// compression was not negotiated with the peer.
-func (c *Conn) EnableWriteCompression(enable bool) {
- c.enableWriteCompression = enable
-}
-
-// SetCompressionLevel sets the flate compression level for subsequent text and
-// binary messages. This function is a noop if compression was not negotiated
-// with the peer. See the compress/flate package for a description of
-// compression levels.
-func (c *Conn) SetCompressionLevel(level int) error {
- if !isValidCompressionLevel(level) {
- return errors.New("websocket: invalid compression level")
- }
- c.compressionLevel = level
- return nil
-}
-
-// FormatCloseMessage formats closeCode and text as a WebSocket close message.
-// An empty message is returned for code CloseNoStatusReceived.
-func FormatCloseMessage(closeCode int, text string) []byte {
- if closeCode == CloseNoStatusReceived {
- // Return empty message because it's illegal to send
- // CloseNoStatusReceived. Return non-nil value in case application
- // checks for nil.
- return []byte{}
- }
- buf := make([]byte, 2+len(text))
- binary.BigEndian.PutUint16(buf, uint16(closeCode))
- copy(buf[2:], text)
- return buf
-}
diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go
deleted file mode 100644
index 8db0cef95..000000000
--- a/vendor/github.com/gorilla/websocket/doc.go
+++ /dev/null
@@ -1,227 +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 implements the WebSocket protocol defined in RFC 6455.
-//
-// Overview
-//
-// The Conn type represents a WebSocket connection. A server application calls
-// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn:
-//
-// var upgrader = websocket.Upgrader{
-// ReadBufferSize: 1024,
-// WriteBufferSize: 1024,
-// }
-//
-// func handler(w http.ResponseWriter, r *http.Request) {
-// conn, err := upgrader.Upgrade(w, r, nil)
-// if err != nil {
-// log.Println(err)
-// return
-// }
-// ... Use conn to send and receive messages.
-// }
-//
-// Call the connection's WriteMessage and ReadMessage methods to send and
-// receive messages as a slice of bytes. This snippet of code shows how to echo
-// messages using these methods:
-//
-// for {
-// messageType, p, err := conn.ReadMessage()
-// if err != nil {
-// log.Println(err)
-// return
-// }
-// if err := conn.WriteMessage(messageType, p); err != nil {
-// log.Println(err)
-// return
-// }
-// }
-//
-// In above snippet of code, p is a []byte and messageType is an int with value
-// websocket.BinaryMessage or websocket.TextMessage.
-//
-// An application can also send and receive messages using the io.WriteCloser
-// and io.Reader interfaces. To send a message, call the connection NextWriter
-// method to get an io.WriteCloser, write the message to the writer and close
-// the writer when done. To receive a message, call the connection NextReader
-// method to get an io.Reader and read until io.EOF is returned. This snippet
-// shows how to echo messages using the NextWriter and NextReader methods:
-//
-// for {
-// messageType, r, err := conn.NextReader()
-// if err != nil {
-// return
-// }
-// w, err := conn.NextWriter(messageType)
-// if err != nil {
-// return err
-// }
-// if _, err := io.Copy(w, r); err != nil {
-// return err
-// }
-// if err := w.Close(); err != nil {
-// return err
-// }
-// }
-//
-// Data Messages
-//
-// The WebSocket protocol distinguishes between text and binary data messages.
-// Text messages are interpreted as UTF-8 encoded text. The interpretation of
-// binary messages is left to the application.
-//
-// This package uses the TextMessage and BinaryMessage integer constants to
-// identify the two data message types. The ReadMessage and NextReader methods
-// return the type of the received message. The messageType argument to the
-// WriteMessage and NextWriter methods specifies the type of a sent message.
-//
-// It is the application's responsibility to ensure that text messages are
-// valid UTF-8 encoded text.
-//
-// Control Messages
-//
-// The WebSocket protocol defines three types of control messages: close, ping
-// and pong. Call the connection WriteControl, WriteMessage or NextWriter
-// methods to send a control message to the peer.
-//
-// Connections handle received close messages by calling the handler function
-// set with the SetCloseHandler method and by returning a *CloseError from the
-// NextReader, ReadMessage or the message Read method. The default close
-// handler sends a close message to the peer.
-//
-// Connections handle received ping messages by calling the handler function
-// set with the SetPingHandler method. The default ping handler sends a pong
-// message to the peer.
-//
-// Connections handle received pong messages by calling the handler function
-// set with the SetPongHandler method. The default pong handler does nothing.
-// If an application sends ping messages, then the application should set a
-// pong handler to receive the corresponding pong.
-//
-// The control message handler functions are called from the NextReader,
-// ReadMessage and message reader Read methods. The default close and ping
-// handlers can block these methods for a short time when the handler writes to
-// the connection.
-//
-// The application must read the connection to process close, ping and pong
-// messages sent from the peer. If the application is not otherwise interested
-// in messages from the peer, then the application should start a goroutine to
-// read and discard messages from the peer. A simple example is:
-//
-// func readLoop(c *websocket.Conn) {
-// for {
-// if _, _, err := c.NextReader(); err != nil {
-// c.Close()
-// break
-// }
-// }
-// }
-//
-// Concurrency
-//
-// Connections support one concurrent reader and one concurrent writer.
-//
-// Applications are responsible for ensuring that no more than one goroutine
-// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
-// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and
-// that no more than one goroutine calls the read methods (NextReader,
-// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)
-// concurrently.
-//
-// The Close and WriteControl methods can be called concurrently with all other
-// methods.
-//
-// Origin Considerations
-//
-// Web browsers allow Javascript applications to open a WebSocket connection to
-// any host. It's up to the server to enforce an origin policy using the Origin
-// request header sent by the browser.
-//
-// The Upgrader calls the function specified in the CheckOrigin field to check
-// the origin. If the CheckOrigin function returns false, then the Upgrade
-// method fails the WebSocket handshake with HTTP status 403.
-//
-// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
-// the handshake if the Origin request header is present and the Origin host is
-// not equal to the Host request header.
-//
-// The deprecated package-level Upgrade function does not perform origin
-// checking. The application is responsible for checking the Origin header
-// before calling the Upgrade function.
-//
-// Buffers
-//
-// Connections buffer network input and output to reduce the number
-// of system calls when reading or writing messages.
-//
-// Write buffers are also used for constructing WebSocket frames. See RFC 6455,
-// Section 5 for a discussion of message framing. A WebSocket frame header is
-// written to the network each time a write buffer is flushed to the network.
-// Decreasing the size of the write buffer can increase the amount of framing
-// overhead on the connection.
-//
-// The buffer sizes in bytes are specified by the ReadBufferSize and
-// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default
-// size of 4096 when a buffer size field is set to zero. The Upgrader reuses
-// buffers created by the HTTP server when a buffer size field is set to zero.
-// The HTTP server buffers have a size of 4096 at the time of this writing.
-//
-// The buffer sizes do not limit the size of a message that can be read or
-// written by a connection.
-//
-// Buffers are held for the lifetime of the connection by default. If the
-// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the
-// write buffer only when writing a message.
-//
-// Applications should tune the buffer sizes to balance memory use and
-// performance. Increasing the buffer size uses more memory, but can reduce the
-// number of system calls to read or write the network. In the case of writing,
-// increasing the buffer size can reduce the number of frame headers written to
-// the network.
-//
-// Some guidelines for setting buffer parameters are:
-//
-// Limit the buffer sizes to the maximum expected message size. Buffers larger
-// than the largest message do not provide any benefit.
-//
-// Depending on the distribution of message sizes, setting the buffer size to
-// a value less than the maximum expected message size can greatly reduce memory
-// use with a small impact on performance. Here's an example: If 99% of the
-// messages are smaller than 256 bytes and the maximum message size is 512
-// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls
-// than a buffer size of 512 bytes. The memory savings is 50%.
-//
-// A write buffer pool is useful when the application has a modest number
-// writes over a large number of connections. when buffers are pooled, a larger
-// buffer size has a reduced impact on total memory use and has the benefit of
-// reducing system calls and frame overhead.
-//
-// Compression EXPERIMENTAL
-//
-// Per message compression extensions (RFC 7692) are experimentally supported
-// by this package in a limited capacity. Setting the EnableCompression option
-// to true in Dialer or Upgrader will attempt to negotiate per message deflate
-// support.
-//
-// var upgrader = websocket.Upgrader{
-// EnableCompression: true,
-// }
-//
-// If compression was successfully negotiated with the connection's peer, any
-// message received in compressed form will be automatically decompressed.
-// All Read methods will return uncompressed bytes.
-//
-// Per message compression of messages written to a connection can be enabled
-// or disabled by calling the corresponding Conn method:
-//
-// conn.EnableWriteCompression(false)
-//
-// Currently this package does not support compression with "context takeover".
-// This means that messages must be compressed and decompressed in isolation,
-// without retaining sliding window or dictionary state across messages. For
-// more details refer to RFC 7692.
-//
-// Use of compression is experimental and may result in decreased performance.
-package websocket
diff --git a/vendor/github.com/gorilla/websocket/join.go b/vendor/github.com/gorilla/websocket/join.go
deleted file mode 100644
index c64f8c829..000000000
--- a/vendor/github.com/gorilla/websocket/join.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 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 (
- "io"
- "strings"
-)
-
-// JoinMessages concatenates received messages to create a single io.Reader.
-// The string term is appended to each message. The returned reader does not
-// support concurrent calls to the Read method.
-func JoinMessages(c *Conn, term string) io.Reader {
- return &joinReader{c: c, term: term}
-}
-
-type joinReader struct {
- c *Conn
- term string
- r io.Reader
-}
-
-func (r *joinReader) Read(p []byte) (int, error) {
- if r.r == nil {
- var err error
- _, r.r, err = r.c.NextReader()
- if err != nil {
- return 0, err
- }
- if r.term != "" {
- r.r = io.MultiReader(r.r, strings.NewReader(r.term))
- }
- }
- n, err := r.r.Read(p)
- if err == io.EOF {
- err = nil
- r.r = nil
- }
- return n, err
-}
diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go
deleted file mode 100644
index dc2c1f641..000000000
--- a/vendor/github.com/gorilla/websocket/json.go
+++ /dev/null
@@ -1,60 +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 (
- "encoding/json"
- "io"
-)
-
-// WriteJSON writes the JSON encoding of v as a message.
-//
-// Deprecated: Use c.WriteJSON instead.
-func WriteJSON(c *Conn, v interface{}) error {
- return c.WriteJSON(v)
-}
-
-// WriteJSON writes the JSON encoding of v as a message.
-//
-// See the documentation for encoding/json Marshal for details about the
-// conversion of Go values to JSON.
-func (c *Conn) WriteJSON(v interface{}) error {
- w, err := c.NextWriter(TextMessage)
- if err != nil {
- return err
- }
- err1 := json.NewEncoder(w).Encode(v)
- err2 := w.Close()
- if err1 != nil {
- return err1
- }
- return err2
-}
-
-// ReadJSON reads the next JSON-encoded message from the connection and stores
-// it in the value pointed to by v.
-//
-// Deprecated: Use c.ReadJSON instead.
-func ReadJSON(c *Conn, v interface{}) error {
- return c.ReadJSON(v)
-}
-
-// ReadJSON reads the next JSON-encoded message from the connection and stores
-// it in the value pointed to by v.
-//
-// See the documentation for the encoding/json Unmarshal function for details
-// about the conversion of JSON to a Go value.
-func (c *Conn) ReadJSON(v interface{}) error {
- _, r, err := c.NextReader()
- if err != nil {
- return err
- }
- err = json.NewDecoder(r).Decode(v)
- if err == io.EOF {
- // One value is expected in the message.
- err = io.ErrUnexpectedEOF
- }
- return err
-}
diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go
deleted file mode 100644
index d0742bf2a..000000000
--- a/vendor/github.com/gorilla/websocket/mask.go
+++ /dev/null
@@ -1,55 +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.
-
-//go:build !appengine
-// +build !appengine
-
-package websocket
-
-import "unsafe"
-
-const wordSize = int(unsafe.Sizeof(uintptr(0)))
-
-func maskBytes(key [4]byte, pos int, b []byte) int {
- // Mask one byte at a time for small buffers.
- if len(b) < 2*wordSize {
- for i := range b {
- b[i] ^= key[pos&3]
- pos++
- }
- return pos & 3
- }
-
- // Mask one byte at a time to word boundary.
- if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
- n = wordSize - n
- for i := range b[:n] {
- b[i] ^= key[pos&3]
- pos++
- }
- b = b[n:]
- }
-
- // Create aligned word size key.
- var k [wordSize]byte
- for i := range k {
- k[i] = key[(pos+i)&3]
- }
- kw := *(*uintptr)(unsafe.Pointer(&k))
-
- // Mask one word at a time.
- n := (len(b) / wordSize) * wordSize
- for i := 0; i < n; i += wordSize {
- *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw
- }
-
- // Mask one byte at a time for remaining bytes.
- b = b[n:]
- for i := range b {
- b[i] ^= key[pos&3]
- pos++
- }
-
- return pos & 3
-}
diff --git a/vendor/github.com/gorilla/websocket/mask_safe.go b/vendor/github.com/gorilla/websocket/mask_safe.go
deleted file mode 100644
index 36250ca7c..000000000
--- a/vendor/github.com/gorilla/websocket/mask_safe.go
+++ /dev/null
@@ -1,16 +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.
-
-//go:build appengine
-// +build appengine
-
-package websocket
-
-func maskBytes(key [4]byte, pos int, b []byte) int {
- for i := range b {
- b[i] ^= key[pos&3]
- pos++
- }
- return pos & 3
-}
diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go
deleted file mode 100644
index c854225e9..000000000
--- a/vendor/github.com/gorilla/websocket/prepared.go
+++ /dev/null
@@ -1,102 +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"
- "net"
- "sync"
- "time"
-)
-
-// PreparedMessage caches on the wire representations of a message payload.
-// Use PreparedMessage to efficiently send a message payload to multiple
-// connections. PreparedMessage is especially useful when compression is used
-// because the CPU and memory expensive compression operation can be executed
-// once for a given set of compression options.
-type PreparedMessage struct {
- messageType int
- data []byte
- mu sync.Mutex
- frames map[prepareKey]*preparedFrame
-}
-
-// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage.
-type prepareKey struct {
- isServer bool
- compress bool
- compressionLevel int
-}
-
-// preparedFrame contains data in wire representation.
-type preparedFrame struct {
- once sync.Once
- data []byte
-}
-
-// NewPreparedMessage returns an initialized PreparedMessage. You can then send
-// it to connection using WritePreparedMessage method. Valid wire
-// representation will be calculated lazily only once for a set of current
-// connection options.
-func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {
- pm := &PreparedMessage{
- messageType: messageType,
- frames: make(map[prepareKey]*preparedFrame),
- data: data,
- }
-
- // Prepare a plain server frame.
- _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})
- if err != nil {
- return nil, err
- }
-
- // To protect against caller modifying the data argument, remember the data
- // copied to the plain server frame.
- pm.data = frameData[len(frameData)-len(data):]
- return pm, nil
-}
-
-func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {
- pm.mu.Lock()
- frame, ok := pm.frames[key]
- if !ok {
- frame = &preparedFrame{}
- pm.frames[key] = frame
- }
- pm.mu.Unlock()
-
- var err error
- frame.once.Do(func() {
- // Prepare a frame using a 'fake' connection.
- // TODO: Refactor code in conn.go to allow more direct construction of
- // the frame.
- mu := make(chan struct{}, 1)
- mu <- struct{}{}
- var nc prepareConn
- c := &Conn{
- conn: &nc,
- mu: mu,
- isServer: key.isServer,
- compressionLevel: key.compressionLevel,
- enableWriteCompression: true,
- writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),
- }
- if key.compress {
- c.newCompressionWriter = compressNoContextTakeover
- }
- err = c.WriteMessage(pm.messageType, pm.data)
- frame.data = nc.buf.Bytes()
- })
- return pm.messageType, frame.data, err
-}
-
-type prepareConn struct {
- buf bytes.Buffer
- net.Conn
-}
-
-func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) }
-func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }
diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go
deleted file mode 100644
index e0f466b72..000000000
--- a/vendor/github.com/gorilla/websocket/proxy.go
+++ /dev/null
@@ -1,77 +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 (
- "bufio"
- "encoding/base64"
- "errors"
- "net"
- "net/http"
- "net/url"
- "strings"
-)
-
-type netDialerFunc func(network, addr string) (net.Conn, error)
-
-func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
- return fn(network, addr)
-}
-
-func init() {
- proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
- return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil
- })
-}
-
-type httpProxyDialer struct {
- proxyURL *url.URL
- forwardDial func(network, addr string) (net.Conn, error)
-}
-
-func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
- hostPort, _ := hostPortNoPort(hpd.proxyURL)
- conn, err := hpd.forwardDial(network, hostPort)
- if err != nil {
- return nil, err
- }
-
- connectHeader := make(http.Header)
- if user := hpd.proxyURL.User; user != nil {
- proxyUser := user.Username()
- if proxyPassword, passwordSet := user.Password(); passwordSet {
- credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
- connectHeader.Set("Proxy-Authorization", "Basic "+credential)
- }
- }
-
- connectReq := &http.Request{
- Method: http.MethodConnect,
- URL: &url.URL{Opaque: addr},
- Host: addr,
- Header: connectHeader,
- }
-
- if err := connectReq.Write(conn); err != nil {
- conn.Close()
- return nil, err
- }
-
- // Read response. It's OK to use and discard buffered reader here becaue
- // the remote server does not speak until spoken to.
- br := bufio.NewReader(conn)
- resp, err := http.ReadResponse(br, connectReq)
- if err != nil {
- conn.Close()
- return nil, err
- }
-
- if resp.StatusCode != 200 {
- conn.Close()
- f := strings.SplitN(resp.Status, " ", 2)
- return nil, errors.New(f[1])
- }
- return conn, nil
-}
diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go
deleted file mode 100644
index bb3359743..000000000
--- a/vendor/github.com/gorilla/websocket/server.go
+++ /dev/null
@@ -1,365 +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"
- "errors"
- "io"
- "net/http"
- "net/url"
- "strings"
- "time"
-)
-
-// HandshakeError describes an error with the handshake from the peer.
-type HandshakeError struct {
- message string
-}
-
-func (e HandshakeError) Error() string { return e.message }
-
-// Upgrader specifies parameters for upgrading an HTTP connection to a
-// WebSocket connection.
-//
-// It is safe to call Upgrader's methods concurrently.
-type Upgrader struct {
- // HandshakeTimeout specifies the duration for the handshake to complete.
- HandshakeTimeout time.Duration
-
- // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer
- // size is zero, then buffers allocated by the HTTP server are used. The
- // I/O buffer sizes do not limit the size of the messages that can be sent
- // or received.
- ReadBufferSize, WriteBufferSize int
-
- // WriteBufferPool is a pool of buffers for write operations. If the value
- // is not set, then write buffers are allocated to the connection for the
- // lifetime of the connection.
- //
- // A pool is most useful when the application has a modest volume of writes
- // across a large number of connections.
- //
- // Applications should use a single pool for each unique value of
- // WriteBufferSize.
- WriteBufferPool BufferPool
-
- // Subprotocols specifies the server's supported protocols in order of
- // preference. If this field is not nil, then the Upgrade method negotiates a
- // subprotocol by selecting the first match in this list with a protocol
- // requested by the client. If there's no match, then no protocol is
- // negotiated (the Sec-Websocket-Protocol header is not included in the
- // handshake response).
- Subprotocols []string
-
- // Error specifies the function for generating HTTP error responses. If Error
- // is nil, then http.Error is used to generate the HTTP response.
- Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
-
- // CheckOrigin returns true if the request Origin header is acceptable. If
- // CheckOrigin is nil, then a safe default is used: return false if the
- // Origin request header is present and the origin host is not equal to
- // request Host header.
- //
- // A CheckOrigin function should carefully validate the request origin to
- // prevent cross-site request forgery.
- CheckOrigin func(r *http.Request) bool
-
- // EnableCompression specify if the server should attempt to negotiate per
- // message compression (RFC 7692). Setting this value to true does not
- // guarantee that compression will be supported. Currently only "no context
- // takeover" modes are supported.
- EnableCompression bool
-}
-
-func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
- err := HandshakeError{reason}
- if u.Error != nil {
- u.Error(w, r, status, err)
- } else {
- w.Header().Set("Sec-Websocket-Version", "13")
- http.Error(w, http.StatusText(status), status)
- }
- return nil, err
-}
-
-// checkSameOrigin returns true if the origin is not set or is equal to the request host.
-func checkSameOrigin(r *http.Request) bool {
- origin := r.Header["Origin"]
- if len(origin) == 0 {
- return true
- }
- u, err := url.Parse(origin[0])
- if err != nil {
- return false
- }
- return equalASCIIFold(u.Host, r.Host)
-}
-
-func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
- if u.Subprotocols != nil {
- clientProtocols := Subprotocols(r)
- for _, serverProtocol := range u.Subprotocols {
- for _, clientProtocol := range clientProtocols {
- if clientProtocol == serverProtocol {
- return clientProtocol
- }
- }
- }
- } else if responseHeader != nil {
- return responseHeader.Get("Sec-Websocket-Protocol")
- }
- return ""
-}
-
-// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
-//
-// The responseHeader is included in the response to the client's upgrade
-// request. Use the responseHeader to specify cookies (Set-Cookie). To specify
-// subprotocols supported by the server, set Upgrader.Subprotocols directly.
-//
-// If the upgrade fails, then Upgrade replies to the client with an HTTP error
-// response.
-func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
- const badHandshake = "websocket: the client is not using the websocket protocol: "
-
- if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
- return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header")
- }
-
- if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
- return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header")
- }
-
- if r.Method != http.MethodGet {
- return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET")
- }
-
- if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header")
- }
-
- if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
- return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported")
- }
-
- checkOrigin := u.CheckOrigin
- if checkOrigin == nil {
- checkOrigin = checkSameOrigin
- }
- if !checkOrigin(r) {
- return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin")
- }
-
- challengeKey := r.Header.Get("Sec-Websocket-Key")
- if !isValidChallengeKey(challengeKey) {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header must be Base64 encoded value of 16-byte in length")
- }
-
- subprotocol := u.selectSubprotocol(r, responseHeader)
-
- // Negotiate PMCE
- var compress bool
- if u.EnableCompression {
- for _, ext := range parseExtensions(r.Header) {
- if ext[""] != "permessage-deflate" {
- continue
- }
- compress = true
- break
- }
- }
-
- h, ok := w.(http.Hijacker)
- if !ok {
- return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
- }
- var brw *bufio.ReadWriter
- netConn, brw, err := h.Hijack()
- if err != nil {
- return u.returnError(w, r, http.StatusInternalServerError, err.Error())
- }
-
- if brw.Reader.Buffered() > 0 {
- netConn.Close()
- return nil, errors.New("websocket: client sent data before handshake is complete")
- }
-
- var br *bufio.Reader
- if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 {
- // Reuse hijacked buffered reader as connection reader.
- br = brw.Reader
- }
-
- buf := bufioWriterBuffer(netConn, brw.Writer)
-
- var writeBuf []byte
- if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 {
- // Reuse hijacked write buffer as connection buffer.
- writeBuf = buf
- }
-
- c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf)
- c.subprotocol = subprotocol
-
- if compress {
- c.newCompressionWriter = compressNoContextTakeover
- c.newDecompressionReader = decompressNoContextTakeover
- }
-
- // Use larger of hijacked buffer and connection write buffer for header.
- p := buf
- if len(c.writeBuf) > len(p) {
- p = c.writeBuf
- }
- p = p[:0]
-
- p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
- p = append(p, computeAcceptKey(challengeKey)...)
- p = append(p, "\r\n"...)
- if c.subprotocol != "" {
- p = append(p, "Sec-WebSocket-Protocol: "...)
- p = append(p, c.subprotocol...)
- p = append(p, "\r\n"...)
- }
- if compress {
- p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
- }
- for k, vs := range responseHeader {
- if k == "Sec-Websocket-Protocol" {
- continue
- }
- for _, v := range vs {
- p = append(p, k...)
- p = append(p, ": "...)
- for i := 0; i < len(v); i++ {
- b := v[i]
- if b <= 31 {
- // prevent response splitting.
- b = ' '
- }
- p = append(p, b)
- }
- p = append(p, "\r\n"...)
- }
- }
- p = append(p, "\r\n"...)
-
- // Clear deadlines set by HTTP server.
- netConn.SetDeadline(time.Time{})
-
- if u.HandshakeTimeout > 0 {
- netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))
- }
- if _, err = netConn.Write(p); err != nil {
- netConn.Close()
- return nil, err
- }
- if u.HandshakeTimeout > 0 {
- netConn.SetWriteDeadline(time.Time{})
- }
-
- return c, nil
-}
-
-// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
-//
-// Deprecated: Use websocket.Upgrader instead.
-//
-// Upgrade does not perform origin checking. The application is responsible for
-// checking the Origin header before calling Upgrade. An example implementation
-// of the same origin policy check is:
-//
-// if req.Header.Get("Origin") != "http://"+req.Host {
-// http.Error(w, "Origin not allowed", http.StatusForbidden)
-// return
-// }
-//
-// If the endpoint supports subprotocols, then the application is responsible
-// for negotiating the protocol used on the connection. Use the Subprotocols()
-// function to get the subprotocols requested by the client. Use the
-// Sec-Websocket-Protocol response header to specify the subprotocol selected
-// by the application.
-//
-// The responseHeader is included in the response to the client's upgrade
-// request. Use the responseHeader to specify cookies (Set-Cookie) and the
-// negotiated subprotocol (Sec-Websocket-Protocol).
-//
-// The connection buffers IO to the underlying network connection. The
-// readBufSize and writeBufSize parameters specify the size of the buffers to
-// use. Messages can be larger than the buffers.
-//
-// If the request is not a valid WebSocket handshake, then Upgrade returns an
-// error of type HandshakeError. Applications should handle this error by
-// replying to the client with an HTTP error response.
-func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {
- u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}
- u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {
- // don't return errors to maintain backwards compatibility
- }
- u.CheckOrigin = func(r *http.Request) bool {
- // allow all connections by default
- return true
- }
- return u.Upgrade(w, r, responseHeader)
-}
-
-// Subprotocols returns the subprotocols requested by the client in the
-// Sec-Websocket-Protocol header.
-func Subprotocols(r *http.Request) []string {
- h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol"))
- if h == "" {
- return nil
- }
- protocols := strings.Split(h, ",")
- for i := range protocols {
- protocols[i] = strings.TrimSpace(protocols[i])
- }
- return protocols
-}
-
-// IsWebSocketUpgrade returns true if the client requested upgrade to the
-// WebSocket protocol.
-func IsWebSocketUpgrade(r *http.Request) bool {
- return tokenListContainsValue(r.Header, "Connection", "upgrade") &&
- tokenListContainsValue(r.Header, "Upgrade", "websocket")
-}
-
-// bufioReaderSize size returns the size of a bufio.Reader.
-func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int {
- // This code assumes that peek on a reset reader returns
- // bufio.Reader.buf[:0].
- // TODO: Use bufio.Reader.Size() after Go 1.10
- br.Reset(originalReader)
- if p, err := br.Peek(0); err == nil {
- return cap(p)
- }
- return 0
-}
-
-// writeHook is an io.Writer that records the last slice passed to it vio
-// io.Writer.Write.
-type writeHook struct {
- p []byte
-}
-
-func (wh *writeHook) Write(p []byte) (int, error) {
- wh.p = p
- return len(p), nil
-}
-
-// bufioWriterBuffer grabs the buffer from a bufio.Writer.
-func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {
- // This code assumes that bufio.Writer.buf[:1] is passed to the
- // bufio.Writer's underlying writer.
- var wh writeHook
- bw.Reset(&wh)
- bw.WriteByte(0)
- bw.Flush()
-
- bw.Reset(originalWriter)
-
- return wh.p[:cap(wh.p)]
-}
diff --git a/vendor/github.com/gorilla/websocket/tls_handshake.go b/vendor/github.com/gorilla/websocket/tls_handshake.go
deleted file mode 100644
index a62b68ccb..000000000
--- a/vendor/github.com/gorilla/websocket/tls_handshake.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build go1.17
-// +build go1.17
-
-package websocket
-
-import (
- "context"
- "crypto/tls"
-)
-
-func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error {
- if err := tlsConn.HandshakeContext(ctx); err != nil {
- return err
- }
- if !cfg.InsecureSkipVerify {
- if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/gorilla/websocket/tls_handshake_116.go b/vendor/github.com/gorilla/websocket/tls_handshake_116.go
deleted file mode 100644
index e1b2b44f6..000000000
--- a/vendor/github.com/gorilla/websocket/tls_handshake_116.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build !go1.17
-// +build !go1.17
-
-package websocket
-
-import (
- "context"
- "crypto/tls"
-)
-
-func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error {
- if err := tlsConn.Handshake(); err != nil {
- return err
- }
- if !cfg.InsecureSkipVerify {
- if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go
deleted file mode 100644
index 31a5dee64..000000000
--- a/vendor/github.com/gorilla/websocket/util.go
+++ /dev/null
@@ -1,298 +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 (
- "crypto/rand"
- "crypto/sha1"
- "encoding/base64"
- "io"
- "net/http"
- "strings"
- "unicode/utf8"
-)
-
-var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
-
-func computeAcceptKey(challengeKey string) string {
- h := sha1.New()
- h.Write([]byte(challengeKey))
- h.Write(keyGUID)
- return base64.StdEncoding.EncodeToString(h.Sum(nil))
-}
-
-func generateChallengeKey() (string, error) {
- p := make([]byte, 16)
- if _, err := io.ReadFull(rand.Reader, p); err != nil {
- return "", err
- }
- return base64.StdEncoding.EncodeToString(p), nil
-}
-
-// Token octets per RFC 2616.
-var isTokenOctet = [256]bool{
- '!': true,
- '#': true,
- '$': true,
- '%': true,
- '&': true,
- '\'': true,
- '*': true,
- '+': true,
- '-': true,
- '.': true,
- '0': true,
- '1': true,
- '2': true,
- '3': true,
- '4': true,
- '5': true,
- '6': true,
- '7': true,
- '8': true,
- '9': true,
- 'A': true,
- 'B': true,
- 'C': true,
- 'D': true,
- 'E': true,
- 'F': true,
- 'G': true,
- 'H': true,
- 'I': true,
- 'J': true,
- 'K': true,
- 'L': true,
- 'M': true,
- 'N': true,
- 'O': true,
- 'P': true,
- 'Q': true,
- 'R': true,
- 'S': true,
- 'T': true,
- 'U': true,
- 'W': true,
- 'V': true,
- 'X': true,
- 'Y': true,
- 'Z': true,
- '^': true,
- '_': true,
- '`': true,
- 'a': true,
- 'b': true,
- 'c': true,
- 'd': true,
- 'e': true,
- 'f': true,
- 'g': true,
- 'h': true,
- 'i': true,
- 'j': true,
- 'k': true,
- 'l': true,
- 'm': true,
- 'n': true,
- 'o': true,
- 'p': true,
- 'q': true,
- 'r': true,
- 's': true,
- 't': true,
- 'u': true,
- 'v': true,
- 'w': true,
- 'x': true,
- 'y': true,
- 'z': true,
- '|': true,
- '~': true,
-}
-
-// skipSpace returns a slice of the string s with all leading RFC 2616 linear
-// whitespace removed.
-func skipSpace(s string) (rest string) {
- i := 0
- for ; i < len(s); i++ {
- if b := s[i]; b != ' ' && b != '\t' {
- break
- }
- }
- return s[i:]
-}
-
-// nextToken returns the leading RFC 2616 token of s and the string following
-// the token.
-func nextToken(s string) (token, rest string) {
- i := 0
- for ; i < len(s); i++ {
- if !isTokenOctet[s[i]] {
- break
- }
- }
- return s[:i], s[i:]
-}
-
-// nextTokenOrQuoted returns the leading token or quoted string per RFC 2616
-// and the string following the token or quoted string.
-func nextTokenOrQuoted(s string) (value string, rest string) {
- if !strings.HasPrefix(s, "\"") {
- return nextToken(s)
- }
- s = s[1:]
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '"':
- return s[:i], s[i+1:]
- case '\\':
- p := make([]byte, len(s)-1)
- j := copy(p, s[:i])
- escape := true
- for i = i + 1; i < len(s); i++ {
- b := s[i]
- switch {
- case escape:
- escape = false
- p[j] = b
- j++
- case b == '\\':
- escape = true
- case b == '"':
- return string(p[:j]), s[i+1:]
- default:
- p[j] = b
- j++
- }
- }
- return "", ""
- }
- }
- return "", ""
-}
-
-// equalASCIIFold returns true if s is equal to t with ASCII case folding as
-// defined in RFC 4790.
-func equalASCIIFold(s, t string) bool {
- for s != "" && t != "" {
- sr, size := utf8.DecodeRuneInString(s)
- s = s[size:]
- tr, size := utf8.DecodeRuneInString(t)
- t = t[size:]
- if sr == tr {
- continue
- }
- if 'A' <= sr && sr <= 'Z' {
- sr = sr + 'a' - 'A'
- }
- if 'A' <= tr && tr <= 'Z' {
- tr = tr + 'a' - 'A'
- }
- if sr != tr {
- return false
- }
- }
- return s == t
-}
-
-// tokenListContainsValue returns true if the 1#token header with the given
-// name contains a token equal to value with ASCII case folding.
-func tokenListContainsValue(header http.Header, name string, value string) bool {
-headers:
- for _, s := range header[name] {
- for {
- var t string
- t, s = nextToken(skipSpace(s))
- if t == "" {
- continue headers
- }
- s = skipSpace(s)
- if s != "" && s[0] != ',' {
- continue headers
- }
- if equalASCIIFold(t, value) {
- return true
- }
- if s == "" {
- continue headers
- }
- s = s[1:]
- }
- }
- return false
-}
-
-// parseExtensions parses WebSocket extensions from a header.
-func parseExtensions(header http.Header) []map[string]string {
- // From RFC 6455:
- //
- // Sec-WebSocket-Extensions = extension-list
- // extension-list = 1#extension
- // extension = extension-token *( ";" extension-param )
- // extension-token = registered-token
- // registered-token = token
- // extension-param = token [ "=" (token | quoted-string) ]
- // ;When using the quoted-string syntax variant, the value
- // ;after quoted-string unescaping MUST conform to the
- // ;'token' ABNF.
-
- var result []map[string]string
-headers:
- for _, s := range header["Sec-Websocket-Extensions"] {
- for {
- var t string
- t, s = nextToken(skipSpace(s))
- if t == "" {
- continue headers
- }
- ext := map[string]string{"": t}
- for {
- s = skipSpace(s)
- if !strings.HasPrefix(s, ";") {
- break
- }
- var k string
- k, s = nextToken(skipSpace(s[1:]))
- if k == "" {
- continue headers
- }
- s = skipSpace(s)
- var v string
- if strings.HasPrefix(s, "=") {
- v, s = nextTokenOrQuoted(skipSpace(s[1:]))
- s = skipSpace(s)
- }
- if s != "" && s[0] != ',' && s[0] != ';' {
- continue headers
- }
- ext[k] = v
- }
- if s != "" && s[0] != ',' {
- continue headers
- }
- result = append(result, ext)
- if s == "" {
- continue headers
- }
- s = s[1:]
- }
- }
- return result
-}
-
-// isValidChallengeKey checks if the argument meets RFC6455 specification.
-func isValidChallengeKey(s string) bool {
- // From RFC6455:
- //
- // A |Sec-WebSocket-Key| header field with a base64-encoded (see
- // Section 4 of [RFC4648]) value that, when decoded, is 16 bytes in
- // length.
-
- if s == "" {
- return false
- }
- decoded, err := base64.StdEncoding.DecodeString(s)
- return err == nil && len(decoded) == 16
-}
diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go
deleted file mode 100644
index 2e668f6b8..000000000
--- a/vendor/github.com/gorilla/websocket/x_net_proxy.go
+++ /dev/null
@@ -1,473 +0,0 @@
-// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
-//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy
-
-// Package proxy provides support for a variety of protocols to proxy network
-// data.
-//
-
-package websocket
-
-import (
- "errors"
- "io"
- "net"
- "net/url"
- "os"
- "strconv"
- "strings"
- "sync"
-)
-
-type proxy_direct struct{}
-
-// Direct is a direct proxy: one that makes network connections directly.
-var proxy_Direct = proxy_direct{}
-
-func (proxy_direct) Dial(network, addr string) (net.Conn, error) {
- return net.Dial(network, addr)
-}
-
-// A PerHost directs connections to a default Dialer unless the host name
-// requested matches one of a number of exceptions.
-type proxy_PerHost struct {
- def, bypass proxy_Dialer
-
- bypassNetworks []*net.IPNet
- bypassIPs []net.IP
- bypassZones []string
- bypassHosts []string
-}
-
-// NewPerHost returns a PerHost Dialer that directs connections to either
-// defaultDialer or bypass, depending on whether the connection matches one of
-// the configured rules.
-func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {
- return &proxy_PerHost{
- def: defaultDialer,
- bypass: bypass,
- }
-}
-
-// Dial connects to the address addr on the given network through either
-// defaultDialer or bypass.
-func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {
- host, _, err := net.SplitHostPort(addr)
- if err != nil {
- return nil, err
- }
-
- return p.dialerForRequest(host).Dial(network, addr)
-}
-
-func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {
- if ip := net.ParseIP(host); ip != nil {
- for _, net := range p.bypassNetworks {
- if net.Contains(ip) {
- return p.bypass
- }
- }
- for _, bypassIP := range p.bypassIPs {
- if bypassIP.Equal(ip) {
- return p.bypass
- }
- }
- return p.def
- }
-
- for _, zone := range p.bypassZones {
- if strings.HasSuffix(host, zone) {
- return p.bypass
- }
- if host == zone[1:] {
- // For a zone ".example.com", we match "example.com"
- // too.
- return p.bypass
- }
- }
- for _, bypassHost := range p.bypassHosts {
- if bypassHost == host {
- return p.bypass
- }
- }
- return p.def
-}
-
-// AddFromString parses a string that contains comma-separated values
-// specifying hosts that should use the bypass proxy. Each value is either an
-// IP address, a CIDR range, a zone (*.example.com) or a host name
-// (localhost). A best effort is made to parse the string and errors are
-// ignored.
-func (p *proxy_PerHost) AddFromString(s string) {
- hosts := strings.Split(s, ",")
- for _, host := range hosts {
- host = strings.TrimSpace(host)
- if len(host) == 0 {
- continue
- }
- if strings.Contains(host, "/") {
- // We assume that it's a CIDR address like 127.0.0.0/8
- if _, net, err := net.ParseCIDR(host); err == nil {
- p.AddNetwork(net)
- }
- continue
- }
- if ip := net.ParseIP(host); ip != nil {
- p.AddIP(ip)
- continue
- }
- if strings.HasPrefix(host, "*.") {
- p.AddZone(host[1:])
- continue
- }
- p.AddHost(host)
- }
-}
-
-// AddIP specifies an IP address that will use the bypass proxy. Note that
-// this will only take effect if a literal IP address is dialed. A connection
-// to a named host will never match an IP.
-func (p *proxy_PerHost) AddIP(ip net.IP) {
- p.bypassIPs = append(p.bypassIPs, ip)
-}
-
-// AddNetwork specifies an IP range that will use the bypass proxy. Note that
-// this will only take effect if a literal IP address is dialed. A connection
-// to a named host will never match.
-func (p *proxy_PerHost) AddNetwork(net *net.IPNet) {
- p.bypassNetworks = append(p.bypassNetworks, net)
-}
-
-// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
-// "example.com" matches "example.com" and all of its subdomains.
-func (p *proxy_PerHost) AddZone(zone string) {
- if strings.HasSuffix(zone, ".") {
- zone = zone[:len(zone)-1]
- }
- if !strings.HasPrefix(zone, ".") {
- zone = "." + zone
- }
- p.bypassZones = append(p.bypassZones, zone)
-}
-
-// AddHost specifies a host name that will use the bypass proxy.
-func (p *proxy_PerHost) AddHost(host string) {
- if strings.HasSuffix(host, ".") {
- host = host[:len(host)-1]
- }
- p.bypassHosts = append(p.bypassHosts, host)
-}
-
-// A Dialer is a means to establish a connection.
-type proxy_Dialer interface {
- // Dial connects to the given address via the proxy.
- Dial(network, addr string) (c net.Conn, err error)
-}
-
-// Auth contains authentication parameters that specific Dialers may require.
-type proxy_Auth struct {
- User, Password string
-}
-
-// FromEnvironment returns the dialer specified by the proxy related variables in
-// the environment.
-func proxy_FromEnvironment() proxy_Dialer {
- allProxy := proxy_allProxyEnv.Get()
- if len(allProxy) == 0 {
- return proxy_Direct
- }
-
- proxyURL, err := url.Parse(allProxy)
- if err != nil {
- return proxy_Direct
- }
- proxy, err := proxy_FromURL(proxyURL, proxy_Direct)
- if err != nil {
- return proxy_Direct
- }
-
- noProxy := proxy_noProxyEnv.Get()
- if len(noProxy) == 0 {
- return proxy
- }
-
- perHost := proxy_NewPerHost(proxy, proxy_Direct)
- perHost.AddFromString(noProxy)
- return perHost
-}
-
-// proxySchemes is a map from URL schemes to a function that creates a Dialer
-// from a URL with such a scheme.
-var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)
-
-// RegisterDialerType takes a URL scheme and a function to generate Dialers from
-// a URL with that scheme and a forwarding Dialer. Registered schemes are used
-// by FromURL.
-func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {
- if proxy_proxySchemes == nil {
- proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))
- }
- proxy_proxySchemes[scheme] = f
-}
-
-// FromURL returns a Dialer given a URL specification and an underlying
-// Dialer for it to make network requests.
-func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {
- var auth *proxy_Auth
- if u.User != nil {
- auth = new(proxy_Auth)
- auth.User = u.User.Username()
- if p, ok := u.User.Password(); ok {
- auth.Password = p
- }
- }
-
- switch u.Scheme {
- case "socks5":
- return proxy_SOCKS5("tcp", u.Host, auth, forward)
- }
-
- // If the scheme doesn't match any of the built-in schemes, see if it
- // was registered by another package.
- if proxy_proxySchemes != nil {
- if f, ok := proxy_proxySchemes[u.Scheme]; ok {
- return f(u, forward)
- }
- }
-
- return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
-}
-
-var (
- proxy_allProxyEnv = &proxy_envOnce{
- names: []string{"ALL_PROXY", "all_proxy"},
- }
- proxy_noProxyEnv = &proxy_envOnce{
- names: []string{"NO_PROXY", "no_proxy"},
- }
-)
-
-// envOnce looks up an environment variable (optionally by multiple
-// names) once. It mitigates expensive lookups on some platforms
-// (e.g. Windows).
-// (Borrowed from net/http/transport.go)
-type proxy_envOnce struct {
- names []string
- once sync.Once
- val string
-}
-
-func (e *proxy_envOnce) Get() string {
- e.once.Do(e.init)
- return e.val
-}
-
-func (e *proxy_envOnce) init() {
- for _, n := range e.names {
- e.val = os.Getenv(n)
- if e.val != "" {
- return
- }
- }
-}
-
-// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
-// with an optional username and password. See RFC 1928 and RFC 1929.
-func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {
- s := &proxy_socks5{
- network: network,
- addr: addr,
- forward: forward,
- }
- if auth != nil {
- s.user = auth.User
- s.password = auth.Password
- }
-
- return s, nil
-}
-
-type proxy_socks5 struct {
- user, password string
- network, addr string
- forward proxy_Dialer
-}
-
-const proxy_socks5Version = 5
-
-const (
- proxy_socks5AuthNone = 0
- proxy_socks5AuthPassword = 2
-)
-
-const proxy_socks5Connect = 1
-
-const (
- proxy_socks5IP4 = 1
- proxy_socks5Domain = 3
- proxy_socks5IP6 = 4
-)
-
-var proxy_socks5Errors = []string{
- "",
- "general failure",
- "connection forbidden",
- "network unreachable",
- "host unreachable",
- "connection refused",
- "TTL expired",
- "command not supported",
- "address type not supported",
-}
-
-// Dial connects to the address addr on the given network via the SOCKS5 proxy.
-func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {
- switch network {
- case "tcp", "tcp6", "tcp4":
- default:
- return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
- }
-
- conn, err := s.forward.Dial(s.network, s.addr)
- if err != nil {
- return nil, err
- }
- if err := s.connect(conn, addr); err != nil {
- conn.Close()
- return nil, err
- }
- return conn, nil
-}
-
-// connect takes an existing connection to a socks5 proxy server,
-// and commands the server to extend that connection to target,
-// which must be a canonical address with a host and port.
-func (s *proxy_socks5) connect(conn net.Conn, target string) error {
- host, portStr, err := net.SplitHostPort(target)
- if err != nil {
- return err
- }
-
- port, err := strconv.Atoi(portStr)
- if err != nil {
- return errors.New("proxy: failed to parse port number: " + portStr)
- }
- if port < 1 || port > 0xffff {
- return errors.New("proxy: port number out of range: " + portStr)
- }
-
- // the size here is just an estimate
- buf := make([]byte, 0, 6+len(host))
-
- buf = append(buf, proxy_socks5Version)
- if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
- buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)
- } else {
- buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)
- }
-
- if _, err := conn.Write(buf); err != nil {
- return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
-
- if _, err := io.ReadFull(conn, buf[:2]); err != nil {
- return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
- if buf[0] != 5 {
- return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
- }
- if buf[1] == 0xff {
- return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
- }
-
- // See RFC 1929
- if buf[1] == proxy_socks5AuthPassword {
- buf = buf[:0]
- buf = append(buf, 1 /* password protocol version */)
- buf = append(buf, uint8(len(s.user)))
- buf = append(buf, s.user...)
- buf = append(buf, uint8(len(s.password)))
- buf = append(buf, s.password...)
-
- if _, err := conn.Write(buf); err != nil {
- return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
-
- if _, err := io.ReadFull(conn, buf[:2]); err != nil {
- return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
-
- if buf[1] != 0 {
- return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
- }
- }
-
- buf = buf[:0]
- buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)
-
- if ip := net.ParseIP(host); ip != nil {
- if ip4 := ip.To4(); ip4 != nil {
- buf = append(buf, proxy_socks5IP4)
- ip = ip4
- } else {
- buf = append(buf, proxy_socks5IP6)
- }
- buf = append(buf, ip...)
- } else {
- if len(host) > 255 {
- return errors.New("proxy: destination host name too long: " + host)
- }
- buf = append(buf, proxy_socks5Domain)
- buf = append(buf, byte(len(host)))
- buf = append(buf, host...)
- }
- buf = append(buf, byte(port>>8), byte(port))
-
- if _, err := conn.Write(buf); err != nil {
- return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
-
- if _, err := io.ReadFull(conn, buf[:4]); err != nil {
- return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
-
- failure := "unknown error"
- if int(buf[1]) < len(proxy_socks5Errors) {
- failure = proxy_socks5Errors[buf[1]]
- }
-
- if len(failure) > 0 {
- return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
- }
-
- bytesToDiscard := 0
- switch buf[3] {
- case proxy_socks5IP4:
- bytesToDiscard = net.IPv4len
- case proxy_socks5IP6:
- bytesToDiscard = net.IPv6len
- case proxy_socks5Domain:
- _, err := io.ReadFull(conn, buf[:1])
- if err != nil {
- return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
- bytesToDiscard = int(buf[0])
- default:
- return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
- }
-
- if cap(buf) < bytesToDiscard {
- buf = make([]byte, bytesToDiscard)
- } else {
- buf = buf[:bytesToDiscard]
- }
- if _, err := io.ReadFull(conn, buf); err != nil {
- return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
-
- // Also need to discard the port number
- if _, err := io.ReadFull(conn, buf[:2]); err != nil {
- return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())
- }
-
- return nil
-}