Modernize invertergui: MQTT write support, HA integration, UI updates
Some checks failed
build / inverter_gui_pipeline (push) Has been cancelled

This commit is contained in:
2026-02-19 12:03:52 +11:00
parent 959d1e3c1f
commit a31a0b4829
460 changed files with 19655 additions and 40205 deletions

View File

@@ -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

View File

@@ -1 +1,25 @@
coverage.coverprofile
# 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

View File

@@ -1,3 +0,0 @@
run:
skip-dirs:
- examples/*.go

View File

@@ -1,27 +1,22 @@
Copyright (c) 2023 The Gorilla Authors. All rights reserved.
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:
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.
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
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
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.

View File

@@ -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 -exclude-dir examples ./...
.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 ./...

View File

@@ -1,13 +1,10 @@
# gorilla/websocket
# Gorilla WebSocket
![testing](https://github.com/gorilla/websocket/actions/workflows/test.yml/badge.svg)
[![codecov](https://codecov.io/github/gorilla/websocket/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/websocket)
[![godoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
[![sourcegraph](https://sourcegraph.com/github.com/gorilla/websocket/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/websocket?badge)
[![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.
![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5)
Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
### Documentation
@@ -17,7 +14,6 @@ Gorilla WebSocket is a [Go](http://golang.org/) implementation of the [WebSocket
* [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)
### Status
@@ -34,3 +30,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).

View File

@@ -11,16 +11,13 @@ import (
"errors"
"fmt"
"io"
"log"
"io/ioutil"
"net"
"net/http"
"net/http/httptrace"
"net/url"
"strings"
"time"
"golang.org/x/net/proxy"
)
// ErrBadHandshake is returned when the server response to opening handshake is
@@ -228,7 +225,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 +290,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
@@ -310,7 +304,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
return nil, nil, err
}
if proxyURL != nil {
dialer, err := proxy.FromURL(proxyURL, netDialerFunc(netDial))
dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))
if err != nil {
return nil, nil, err
}
@@ -336,9 +330,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()
}
}()
@@ -408,7 +400,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
// debugging.
buf := make([]byte, 1024)
n, _ := io.ReadFull(resp.Body, buf)
resp.Body = io.NopCloser(bytes.NewReader(buf[:n]))
resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
return nil, resp, ErrBadHandshake
}
@@ -426,19 +418,17 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
break
}
resp.Body = io.NopCloser(bytes.NewReader([]byte{}))
resp.Body = ioutil.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
}
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
if cfg == nil {
return &tls.Config{MinVersion: tls.VersionTLS12}
return &tls.Config{}
}
return cfg.Clone()
}

View File

@@ -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
}

View File

@@ -6,11 +6,11 @@ package websocket
import (
"bufio"
"crypto/rand"
"encoding/binary"
"errors"
"io"
"log"
"io/ioutil"
"math/rand"
"net"
"strconv"
"strings"
@@ -181,20 +181,13 @@ var (
errInvalidControlFrame = errors.New("websocket: invalid control frame")
)
// maskRand is an io.Reader for generating mask bytes. The reader is initialized
// to crypto/rand Reader. Tests swap the reader to a math/rand reader for
// reproducible results.
var maskRand = rand.Reader
// newMaskKey returns a new 32 bit value for masking client frames.
func newMaskKey() [4]byte {
var k [4]byte
_, _ = io.ReadFull(maskRand, k[:])
return k
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 {
if e, ok := err.(net.Error); ok && e.Temporary() {
err = &netError{msg: e.Error(), timeout: e.Timeout()}
}
return err
@@ -379,9 +372,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 +387,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 +397,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
}
@@ -449,7 +438,7 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
d := 1000 * time.Hour
if !deadline.IsZero() {
d = time.Until(deadline)
d = deadline.Sub(time.Now())
if d < 0 {
return errWriteTimeout
}
@@ -471,15 +460,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 +477,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 +630,7 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error {
}
if final {
_ = w.endMessage(errWriteClosed)
w.endMessage(errWriteClosed)
return nil
}
@@ -810,7 +795,7 @@ func (c *Conn) advanceFrame() (int, error) {
// 1. Skip remainder of previous frame.
if c.readRemaining > 0 {
if _, err := io.CopyN(io.Discard, c.br, c.readRemaining); err != nil {
if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
return noFrame, err
}
}
@@ -832,9 +817,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 +922,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 +934,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 +981,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 +998,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
}
@@ -1079,9 +1054,7 @@ func (r *messageReader) Read(b []byte) (int, error) {
}
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
}
@@ -1121,7 +1094,7 @@ func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
if err != nil {
return messageType, nil, err
}
p, err = io.ReadAll(r)
p, err = ioutil.ReadAll(r)
return messageType, p, err
}
@@ -1163,9 +1136,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
}
}
@@ -1190,7 +1161,7 @@ func (c *Conn) SetPingHandler(h func(appData string) error) {
err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
if err == ErrCloseSent {
return nil
} else if _, ok := err.(net.Error); ok {
} else if e, ok := err.(net.Error); ok && e.Temporary() {
return nil
}
return err

View File

@@ -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
}

View File

@@ -8,13 +8,10 @@ import (
"bufio"
"encoding/base64"
"errors"
"log"
"net"
"net/http"
"net/url"
"strings"
"golang.org/x/net/proxy"
)
type netDialerFunc func(network, addr string) (net.Conn, error)
@@ -24,7 +21,7 @@ func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
}
func init() {
proxy.RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy.Dialer) (proxy.Dialer, error) {
proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil
})
}
@@ -58,9 +55,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 +64,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)
}
conn.Close()
f := strings.SplitN(resp.Status, " ", 2)
return nil, errors.New(f[1])
}

View File

@@ -8,7 +8,6 @@ import (
"bufio"
"errors"
"io"
"log"
"net/http"
"net/url"
"strings"
@@ -184,9 +183,7 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
}
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 +248,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 +356,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)

View File

@@ -1,3 +1,6 @@
//go:build go1.17
// +build go1.17
package websocket
import (

View File

@@ -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))