diff options
Diffstat (limited to 'vendor/github.com/gorilla/websocket')
| -rw-r--r-- | vendor/github.com/gorilla/websocket/.golangci.yml | 12 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/LICENSE | 2 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/README.md | 12 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/client.go | 17 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/compression.go | 9 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/conn.go | 103 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/mask.go | 4 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/proxy.go | 15 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/server.go | 50 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/tls_handshake_116.go | 21 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/util.go | 4 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/websocket/x_net_proxy.go | 473 | 
12 files changed, 580 insertions, 142 deletions
diff --git a/vendor/github.com/gorilla/websocket/.golangci.yml b/vendor/github.com/gorilla/websocket/.golangci.yml index 34882139e..44cf86a06 100644 --- a/vendor/github.com/gorilla/websocket/.golangci.yml +++ b/vendor/github.com/gorilla/websocket/.golangci.yml @@ -1,3 +1,13 @@  run: -  skip-dirs: +  timeout: "5m" +  # will not run golangci-lint against *_test.go +  tests: false +issues: +  exclude-dirs:      - examples/*.go +  exclude-rules: +  # excluding error checks from all the .go files +    - path: ./*.go +      linters: +        - errcheck + diff --git a/vendor/github.com/gorilla/websocket/LICENSE b/vendor/github.com/gorilla/websocket/LICENSE index bb9d80bc9..8692af650 100644 --- a/vendor/github.com/gorilla/websocket/LICENSE +++ b/vendor/github.com/gorilla/websocket/LICENSE @@ -24,4 +24,4 @@ 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. +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md index 1fd5e9c4e..525a62a92 100644 --- a/vendor/github.com/gorilla/websocket/README.md +++ b/vendor/github.com/gorilla/websocket/README.md @@ -13,11 +13,11 @@ Gorilla WebSocket is a [Go](http://golang.org/) implementation of the [WebSocket  ### 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) -* [Write buffer pool example](https://github.com/gorilla/websocket/tree/master/examples/bufferpool) +* [Chat example](https://github.com/gorilla/websocket/tree/main/examples/chat) +* [Command example](https://github.com/gorilla/websocket/tree/main/examples/command) +* [Client and server example](https://github.com/gorilla/websocket/tree/main/examples/echo) +* [File watch example](https://github.com/gorilla/websocket/tree/main/examples/filewatch) +* [Write buffer pool example](https://github.com/gorilla/websocket/tree/main/examples/bufferpool)  ### Status @@ -33,4 +33,4 @@ package API is stable.  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). +subdirectory](https://github.com/gorilla/websocket/tree/main/examples/autobahn). diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go index 815b0ca5c..7023e1176 100644 --- a/vendor/github.com/gorilla/websocket/client.go +++ b/vendor/github.com/gorilla/websocket/client.go @@ -11,8 +11,6 @@ import (  	"errors"  	"fmt"  	"io" -	"log" -  	"net"  	"net/http"  	"net/http/httptrace" @@ -228,7 +226,6 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h  			k == "Connection" ||  			k == "Sec-Websocket-Key" ||  			k == "Sec-Websocket-Version" || -			//#nosec G101 (CWE-798): Potential HTTP request smuggling via parameter pollution  			k == "Sec-Websocket-Extensions" ||  			(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):  			return nil, nil, errors.New("websocket: duplicate header not allowed: " + k) @@ -294,9 +291,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h  			}  			err = c.SetDeadline(deadline)  			if err != nil { -				if err := c.Close(); err != nil { -					log.Printf("websocket: failed to close network connection: %v", err) -				} +				c.Close()  				return nil, err  			}  			return c, nil @@ -336,9 +331,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h  	defer func() {  		if netConn != nil { -			if err := netConn.Close(); err != nil { -				log.Printf("websocket: failed to close network connection: %v", err) -			} +			netConn.Close()  		}  	}() @@ -399,7 +392,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h  		}  	} -	if resp.StatusCode != 101 || +	if resp.StatusCode != http.StatusSwitchingProtocols ||  		!tokenListContainsValue(resp.Header, "Upgrade", "websocket") ||  		!tokenListContainsValue(resp.Header, "Connection", "upgrade") ||  		resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) { @@ -429,9 +422,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h  	resp.Body = io.NopCloser(bytes.NewReader([]byte{}))  	conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") -	if err := netConn.SetDeadline(time.Time{}); err != nil { -		return nil, nil, err -	} +	netConn.SetDeadline(time.Time{})  	netConn = nil // to avoid close in defer.  	return conn, resp, nil  } diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go index 9fed0ef52..813ffb1e8 100644 --- a/vendor/github.com/gorilla/websocket/compression.go +++ b/vendor/github.com/gorilla/websocket/compression.go @@ -8,7 +8,6 @@ import (  	"compress/flate"  	"errors"  	"io" -	"log"  	"strings"  	"sync"  ) @@ -34,9 +33,7 @@ func decompressNoContextTakeover(r io.Reader) io.ReadCloser {  		"\x01\x00\x00\xff\xff"  	fr, _ := flateReaderPool.Get().(io.ReadCloser) -	if err := fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil); err != nil { -		panic(err) -	} +	fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)  	return &flateReadWrapper{fr}  } @@ -135,9 +132,7 @@ func (r *flateReadWrapper) Read(p []byte) (int, error) {  		// Preemptively place the reader back in the pool. This helps with  		// scenarios where the application does not call NextReader() soon after  		// this final read. -		if err := r.Close(); err != nil { -			log.Printf("websocket: flateReadWrapper.Close() returned error: %v", err) -		} +		r.Close()  	}  	return n, err  } diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go index 221e6cf79..49399b120 100644 --- a/vendor/github.com/gorilla/websocket/conn.go +++ b/vendor/github.com/gorilla/websocket/conn.go @@ -10,7 +10,6 @@ import (  	"encoding/binary"  	"errors"  	"io" -	"log"  	"net"  	"strconv"  	"strings" @@ -193,13 +192,6 @@ func newMaskKey() [4]byte {  	return k  } -func hideTempErr(err error) error { -	if e, ok := err.(net.Error); ok { -		err = &netError{msg: e.Error(), timeout: e.Timeout()} -	} -	return err -} -  func isControl(frameType int) bool {  	return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage  } @@ -365,7 +357,6 @@ func (c *Conn) RemoteAddr() net.Addr {  // Write methods  func (c *Conn) writeFatal(err error) error { -	err = hideTempErr(err)  	c.writeErrMu.Lock()  	if c.writeErr == nil {  		c.writeErr = err @@ -379,9 +370,7 @@ func (c *Conn) read(n int) ([]byte, error) {  	if err == io.EOF {  		err = errUnexpectedEOF  	} -	if _, err := c.br.Discard(len(p)); err != nil { -		return p, err -	} +	c.br.Discard(len(p))  	return p, err  } @@ -396,9 +385,7 @@ func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error  		return err  	} -	if err := c.conn.SetWriteDeadline(deadline); err != nil { -		return c.writeFatal(err) -	} +	c.conn.SetWriteDeadline(deadline)  	if len(buf1) == 0 {  		_, err = c.conn.Write(buf0)  	} else { @@ -408,7 +395,7 @@ func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error  		return c.writeFatal(err)  	}  	if frameType == CloseMessage { -		_ = c.writeFatal(ErrCloseSent) +		c.writeFatal(ErrCloseSent)  	}  	return nil  } @@ -447,21 +434,27 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er  		maskBytes(key, 0, buf[6:])  	} -	d := 1000 * time.Hour -	if !deadline.IsZero() { -		d = time.Until(deadline) +	if deadline.IsZero() { +		// No timeout for zero time. +		<-c.mu +	} else { +		d := time.Until(deadline)  		if d < 0 {  			return errWriteTimeout  		} +		select { +		case <-c.mu: +		default: +			timer := time.NewTimer(d) +			select { +			case <-c.mu: +				timer.Stop() +			case <-timer.C: +				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() @@ -471,15 +464,13 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er  		return err  	} -	if err := c.conn.SetWriteDeadline(deadline); err != nil { -		return c.writeFatal(err) -	} +	c.conn.SetWriteDeadline(deadline)  	_, err = c.conn.Write(buf)  	if err != nil {  		return c.writeFatal(err)  	}  	if messageType == CloseMessage { -		_ = c.writeFatal(ErrCloseSent) +		c.writeFatal(ErrCloseSent)  	}  	return err  } @@ -490,9 +481,7 @@ func (c *Conn) beginMessage(mw *messageWriter, messageType int) error {  	// probably better to return an error in this situation, but we cannot  	// change this without breaking existing applications.  	if c.writer != nil { -		if err := c.writer.Close(); err != nil { -			log.Printf("websocket: discarding writer close error: %v", err) -		} +		c.writer.Close()  		c.writer = nil  	} @@ -645,7 +634,7 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error {  	}  	if final { -		_ = w.endMessage(errWriteClosed) +		w.endMessage(errWriteClosed)  		return nil  	} @@ -832,9 +821,7 @@ func (c *Conn) advanceFrame() (int, error) {  	rsv2 := p[0]&rsv2Bit != 0  	rsv3 := p[0]&rsv3Bit != 0  	mask := p[1]&maskBit != 0 -	if err := c.setReadRemaining(int64(p[1] & 0x7f)); err != nil { -		return noFrame, err -	} +	c.setReadRemaining(int64(p[1] & 0x7f))  	c.readDecompress = false  	if rsv1 { @@ -939,9 +926,7 @@ func (c *Conn) advanceFrame() (int, error) {  		}  		if c.readLimit > 0 && c.readLength > c.readLimit { -			if err := c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)); err != nil { -				return noFrame, err -			} +			c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))  			return noFrame, ErrReadLimit  		} @@ -953,9 +938,7 @@ func (c *Conn) advanceFrame() (int, error) {  	var payload []byte  	if c.readRemaining > 0 {  		payload, err = c.read(int(c.readRemaining)) -		if err := c.setReadRemaining(0); err != nil { -			return noFrame, err -		} +		c.setReadRemaining(0)  		if err != nil {  			return noFrame, err  		} @@ -1002,9 +985,7 @@ func (c *Conn) handleProtocolError(message string) error {  	if len(data) > maxControlFramePayloadSize {  		data = data[:maxControlFramePayloadSize]  	} -	if err := c.WriteControl(CloseMessage, data, time.Now().Add(writeWait)); err != nil { -		return err -	} +	c.WriteControl(CloseMessage, data, time.Now().Add(writeWait))  	return errors.New("websocket: " + message)  } @@ -1021,9 +1002,7 @@ func (c *Conn) handleProtocolError(message string) error {  func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {  	// Close previous reader, only relevant for decompression.  	if c.reader != nil { -		if err := c.reader.Close(); err != nil { -			log.Printf("websocket: discarding reader close error: %v", err) -		} +		c.reader.Close()  		c.reader = nil  	} @@ -1033,7 +1012,7 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {  	for c.readErr == nil {  		frameType, err := c.advanceFrame()  		if err != nil { -			c.readErr = hideTempErr(err) +			c.readErr = err  			break  		} @@ -1073,15 +1052,13 @@ func (r *messageReader) Read(b []byte) (int, error) {  				b = b[:c.readRemaining]  			}  			n, err := c.br.Read(b) -			c.readErr = hideTempErr(err) +			c.readErr = err  			if c.isServer {  				c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])  			}  			rem := c.readRemaining  			rem -= int64(n) -			if err := c.setReadRemaining(rem); err != nil { -				return 0, err -			} +			c.setReadRemaining(rem)  			if c.readRemaining > 0 && c.readErr == io.EOF {  				c.readErr = errUnexpectedEOF  			} @@ -1096,7 +1073,7 @@ func (r *messageReader) Read(b []byte) (int, error) {  		frameType, err := c.advanceFrame()  		switch {  		case err != nil: -			c.readErr = hideTempErr(err) +			c.readErr = err  		case frameType == TextMessage || frameType == BinaryMessage:  			c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")  		} @@ -1163,9 +1140,7 @@ func (c *Conn) SetCloseHandler(h func(code int, text string) error) {  	if h == nil {  		h = func(code int, text string) error {  			message := FormatCloseMessage(code, "") -			if err := c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)); err != nil { -				return err -			} +			c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))  			return nil  		}  	} @@ -1265,3 +1240,15 @@ func FormatCloseMessage(closeCode int, text string) []byte {  	copy(buf[2:], text)  	return buf  } + +var messageTypes = map[int]string{ +	TextMessage:   "TextMessage", +	BinaryMessage: "BinaryMessage", +	CloseMessage:  "CloseMessage", +	PingMessage:   "PingMessage", +	PongMessage:   "PongMessage", +} + +func FormatMessageType(mt int) string { +	return messageTypes[mt] +} diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go index 67d0968be..d0742bf2a 100644 --- a/vendor/github.com/gorilla/websocket/mask.go +++ b/vendor/github.com/gorilla/websocket/mask.go @@ -9,7 +9,6 @@ package websocket  import "unsafe" -// #nosec G103 -- (CWE-242) Has been audited  const wordSize = int(unsafe.Sizeof(uintptr(0)))  func maskBytes(key [4]byte, pos int, b []byte) int { @@ -23,7 +22,6 @@ func maskBytes(key [4]byte, pos int, b []byte) int {  	}  	// Mask one byte at a time to word boundary. -	//#nosec G103 -- (CWE-242) Has been audited  	if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {  		n = wordSize - n  		for i := range b[:n] { @@ -38,13 +36,11 @@ func maskBytes(key [4]byte, pos int, b []byte) int {  	for i := range k {  		k[i] = key[(pos+i)&3]  	} -	//#nosec G103 -- (CWE-242) Has been audited  	kw := *(*uintptr)(unsafe.Pointer(&k))  	// Mask one word at a time.  	n := (len(b) / wordSize) * wordSize  	for i := 0; i < n; i += wordSize { -		//#nosec G103 -- (CWE-242) Has been audited  		*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw  	} diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go index 80f55d1ea..3c570c26f 100644 --- a/vendor/github.com/gorilla/websocket/proxy.go +++ b/vendor/github.com/gorilla/websocket/proxy.go @@ -8,7 +8,6 @@ import (  	"bufio"  	"encoding/base64"  	"errors" -	"log"  	"net"  	"net/http"  	"net/url" @@ -58,9 +57,7 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error)  	}  	if err := connectReq.Write(conn); err != nil { -		if err := conn.Close(); err != nil { -			log.Printf("httpProxyDialer: failed to close connection: %v", err) -		} +		conn.Close()  		return nil, err  	} @@ -69,16 +66,12 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error)  	br := bufio.NewReader(conn)  	resp, err := http.ReadResponse(br, connectReq)  	if err != nil { -		if err := conn.Close(); err != nil { -			log.Printf("httpProxyDialer: failed to close connection: %v", err) -		} +		conn.Close()  		return nil, err  	} -	if resp.StatusCode != 200 { -		if err := conn.Close(); err != nil { -			log.Printf("httpProxyDialer: failed to close connection: %v", err) -		} +	if resp.StatusCode != http.StatusOK { +		conn.Close()  		f := strings.SplitN(resp.Status, " ", 2)  		return nil, errors.New(f[1])  	} diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go index 1e720e1da..fda75ff0d 100644 --- a/vendor/github.com/gorilla/websocket/server.go +++ b/vendor/github.com/gorilla/websocket/server.go @@ -8,7 +8,6 @@ import (  	"bufio"  	"errors"  	"io" -	"log"  	"net/http"  	"net/url"  	"strings" @@ -34,6 +33,7 @@ type Upgrader struct {  	// 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. +	// The default value is 4096 bytes, 4kb.  	ReadBufferSize, WriteBufferSize int  	// WriteBufferPool is a pool of buffers for write operations. If the value @@ -102,8 +102,8 @@ func checkSameOrigin(r *http.Request) bool {  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 { +		for _, clientProtocol := range clientProtocols { +			for _, serverProtocol := range u.Subprotocols {  				if clientProtocol == serverProtocol {  					return clientProtocol  				} @@ -173,20 +173,13 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade  		}  	} -	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() +	netConn, brw, err := http.NewResponseController(w).Hijack()  	if err != nil {  		return u.returnError(w, r, http.StatusInternalServerError, err.Error())  	}  	if brw.Reader.Buffered() > 0 { -		if err := netConn.Close(); err != nil { -			log.Printf("websocket: failed to close network connection: %v", err) -		} +		netConn.Close()  		return nil, errors.New("websocket: client sent data before handshake is complete")  	} @@ -251,34 +244,17 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade  	p = append(p, "\r\n"...)  	// Clear deadlines set by HTTP server. -	if err := netConn.SetDeadline(time.Time{}); err != nil { -		if err := netConn.Close(); err != nil { -			log.Printf("websocket: failed to close network connection: %v", err) -		} -		return nil, err -	} +	netConn.SetDeadline(time.Time{})  	if u.HandshakeTimeout > 0 { -		if err := netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)); err != nil { -			if err := netConn.Close(); err != nil { -				log.Printf("websocket: failed to close network connection: %v", err) -			} -			return nil, err -		} +		netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))  	}  	if _, err = netConn.Write(p); err != nil { -		if err := netConn.Close(); err != nil { -			log.Printf("websocket: failed to close network connection: %v", err) -		} +		netConn.Close()  		return nil, err  	}  	if u.HandshakeTimeout > 0 { -		if err := netConn.SetWriteDeadline(time.Time{}); err != nil { -			if err := netConn.Close(); err != nil { -				log.Printf("websocket: failed to close network connection: %v", err) -			} -			return nil, err -		} +		netConn.SetWriteDeadline(time.Time{})  	}  	return c, nil @@ -376,12 +352,8 @@ func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {  	// bufio.Writer's underlying writer.  	var wh writeHook  	bw.Reset(&wh) -	if err := bw.WriteByte(0); err != nil { -		panic(err) -	} -	if err := bw.Flush(); err != nil { -		log.Printf("websocket: bufioWriterBuffer: Flush: %v", err) -	} +	bw.WriteByte(0) +	bw.Flush()  	bw.Reset(originalWriter) diff --git a/vendor/github.com/gorilla/websocket/tls_handshake_116.go b/vendor/github.com/gorilla/websocket/tls_handshake_116.go new file mode 100644 index 000000000..e1b2b44f6 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/tls_handshake_116.go @@ -0,0 +1,21 @@ +//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 index 9b1a629bf..31a5dee64 100644 --- a/vendor/github.com/gorilla/websocket/util.go +++ b/vendor/github.com/gorilla/websocket/util.go @@ -6,7 +6,7 @@ package websocket  import (  	"crypto/rand" -	"crypto/sha1" //#nosec G505 -- (CWE-327) https://datatracker.ietf.org/doc/html/rfc6455#page-54 +	"crypto/sha1"  	"encoding/base64"  	"io"  	"net/http" @@ -17,7 +17,7 @@ import (  var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")  func computeAcceptKey(challengeKey string) string { -	h := sha1.New() //#nosec G401 -- (CWE-326) https://datatracker.ietf.org/doc/html/rfc6455#page-54 +	h := sha1.New()  	h.Write([]byte(challengeKey))  	h.Write(keyGUID)  	return base64.StdEncoding.EncodeToString(h.Sum(nil)) diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go new file mode 100644 index 000000000..2e668f6b8 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/x_net_proxy.go @@ -0,0 +1,473 @@ +// 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 +}  | 
