mirror of https://github.com/gorilla/websocket.git
Compare commits
No commits in common. "81ab9ae4797e48947a8509aee8d4ff136b3eafb7" and "ed37eca2cf9dd99714f890bc64d272443c73674f" have entirely different histories.
81ab9ae479
...
ed37eca2cf
|
@ -67,4 +67,4 @@ workflows:
|
||||||
- test:
|
- test:
|
||||||
matrix:
|
matrix:
|
||||||
parameters:
|
parameters:
|
||||||
version: ["1.22", "1.21", "1.20"]
|
version: ["1.18", "1.17", "1.16"]
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptrace"
|
"net/http/httptrace"
|
||||||
|
@ -399,7 +400,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||||
// debugging.
|
// debugging.
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
n, _ := io.ReadFull(resp.Body, buf)
|
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
|
return nil, resp, ErrBadHandshake
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +418,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.Body = io.NopCloser(bytes.NewReader([]byte{}))
|
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||||
conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
|
conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
|
||||||
|
|
||||||
netConn.SetDeadline(time.Time{})
|
netConn.SetDeadline(time.Time{})
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -23,7 +24,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -45,15 +45,12 @@ var cstDialer = Dialer{
|
||||||
HandshakeTimeout: 30 * time.Second,
|
HandshakeTimeout: 30 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
type cstHandler struct {
|
type cstHandler struct{ *testing.T }
|
||||||
*testing.T
|
|
||||||
s *cstServer
|
|
||||||
}
|
|
||||||
|
|
||||||
type cstServer struct {
|
type cstServer struct {
|
||||||
URL string
|
*httptest.Server
|
||||||
Server *httptest.Server
|
URL string
|
||||||
wg sync.WaitGroup
|
t *testing.T
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -62,15 +59,9 @@ const (
|
||||||
cstRequestURI = cstPath + "?" + cstRawQuery
|
cstRequestURI = cstPath + "?" + cstRawQuery
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *cstServer) Close() {
|
|
||||||
s.Server.Close()
|
|
||||||
// Wait for handler functions to complete.
|
|
||||||
s.wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newServer(t *testing.T) *cstServer {
|
func newServer(t *testing.T) *cstServer {
|
||||||
var s cstServer
|
var s cstServer
|
||||||
s.Server = httptest.NewServer(cstHandler{T: t, s: &s})
|
s.Server = httptest.NewServer(cstHandler{t})
|
||||||
s.Server.URL += cstRequestURI
|
s.Server.URL += cstRequestURI
|
||||||
s.URL = makeWsProto(s.Server.URL)
|
s.URL = makeWsProto(s.Server.URL)
|
||||||
return &s
|
return &s
|
||||||
|
@ -78,19 +69,13 @@ func newServer(t *testing.T) *cstServer {
|
||||||
|
|
||||||
func newTLSServer(t *testing.T) *cstServer {
|
func newTLSServer(t *testing.T) *cstServer {
|
||||||
var s cstServer
|
var s cstServer
|
||||||
s.Server = httptest.NewTLSServer(cstHandler{T: t, s: &s})
|
s.Server = httptest.NewTLSServer(cstHandler{t})
|
||||||
s.Server.URL += cstRequestURI
|
s.Server.URL += cstRequestURI
|
||||||
s.URL = makeWsProto(s.Server.URL)
|
s.URL = makeWsProto(s.Server.URL)
|
||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t cstHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (t cstHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Because tests wait for a response from a server, we are guaranteed that
|
|
||||||
// the wait group count is incremented before the test waits on the group
|
|
||||||
// in the call to (*cstServer).Close().
|
|
||||||
t.s.wg.Add(1)
|
|
||||||
defer t.s.wg.Done()
|
|
||||||
|
|
||||||
if r.URL.Path != cstPath {
|
if r.URL.Path != cstPath {
|
||||||
t.Logf("path=%v, want %v", r.URL.Path, cstPath)
|
t.Logf("path=%v, want %v", r.URL.Path, cstPath)
|
||||||
http.Error(w, "bad path", http.StatusBadRequest)
|
http.Error(w, "bad path", http.StatusBadRequest)
|
||||||
|
@ -564,7 +549,7 @@ func TestRespOnBadHandshake(t *testing.T) {
|
||||||
t.Errorf("resp.StatusCode=%d, want %d", resp.StatusCode, expectedStatus)
|
t.Errorf("resp.StatusCode=%d, want %d", resp.StatusCode, expectedStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := io.ReadAll(resp.Body)
|
p, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("ReadFull(resp.Body) returned error %v", err)
|
t.Fatalf("ReadFull(resp.Body) returned error %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ func textMessages(num int) [][]byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkWriteNoCompression(b *testing.B) {
|
func BenchmarkWriteNoCompression(b *testing.B) {
|
||||||
w := io.Discard
|
w := ioutil.Discard
|
||||||
c := newTestConn(nil, w, false)
|
c := newTestConn(nil, w, false)
|
||||||
messages := textMessages(100)
|
messages := textMessages(100)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
@ -52,7 +53,7 @@ func BenchmarkWriteNoCompression(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkWriteWithCompression(b *testing.B) {
|
func BenchmarkWriteWithCompression(b *testing.B) {
|
||||||
w := io.Discard
|
w := ioutil.Discard
|
||||||
c := newTestConn(nil, w, false)
|
c := newTestConn(nil, w, false)
|
||||||
messages := textMessages(100)
|
messages := textMessages(100)
|
||||||
c.enableWriteCompression = true
|
c.enableWriteCompression = true
|
||||||
|
|
5
conn.go
5
conn.go
|
@ -9,6 +9,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -794,7 +795,7 @@ func (c *Conn) advanceFrame() (int, error) {
|
||||||
// 1. Skip remainder of previous frame.
|
// 1. Skip remainder of previous frame.
|
||||||
|
|
||||||
if c.readRemaining > 0 {
|
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
|
return noFrame, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1093,7 +1094,7 @@ func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return messageType, nil, err
|
return messageType, nil, err
|
||||||
}
|
}
|
||||||
p, err = io.ReadAll(r)
|
p, err = ioutil.ReadAll(r)
|
||||||
return messageType, p, err
|
return messageType, p, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ package websocket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -44,7 +45,7 @@ func newBroadcastConn(c *Conn) *broadcastConn {
|
||||||
|
|
||||||
func newBroadcastBench(usePrepared, compression bool) *broadcastBench {
|
func newBroadcastBench(usePrepared, compression bool) *broadcastBench {
|
||||||
bench := &broadcastBench{
|
bench := &broadcastBench{
|
||||||
w: io.Discard,
|
w: ioutil.Discard,
|
||||||
doneCh: make(chan struct{}),
|
doneCh: make(chan struct{}),
|
||||||
closeCh: make(chan struct{}),
|
closeCh: make(chan struct{}),
|
||||||
usePrepared: usePrepared,
|
usePrepared: usePrepared,
|
||||||
|
|
11
conn_test.go
11
conn_test.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -124,7 +125,7 @@ func TestFraming(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("frame size: %d", n)
|
t.Logf("frame size: %d", n)
|
||||||
rbuf, err := io.ReadAll(r)
|
rbuf, err := ioutil.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%s: ReadFull() returned rbuf, %v", name, err)
|
t.Errorf("%s: ReadFull() returned rbuf, %v", name, err)
|
||||||
continue
|
continue
|
||||||
|
@ -366,7 +367,7 @@ func TestCloseFrameBeforeFinalMessageFrame(t *testing.T) {
|
||||||
if op != BinaryMessage || err != nil {
|
if op != BinaryMessage || err != nil {
|
||||||
t.Fatalf("NextReader() returned %d, %v", op, err)
|
t.Fatalf("NextReader() returned %d, %v", op, err)
|
||||||
}
|
}
|
||||||
_, err = io.Copy(io.Discard, r)
|
_, err = io.Copy(ioutil.Discard, r)
|
||||||
if !reflect.DeepEqual(err, expectedErr) {
|
if !reflect.DeepEqual(err, expectedErr) {
|
||||||
t.Fatalf("io.Copy() returned %v, want %v", err, expectedErr)
|
t.Fatalf("io.Copy() returned %v, want %v", err, expectedErr)
|
||||||
}
|
}
|
||||||
|
@ -400,7 +401,7 @@ func TestEOFWithinFrame(t *testing.T) {
|
||||||
if op != BinaryMessage || err != nil {
|
if op != BinaryMessage || err != nil {
|
||||||
t.Fatalf("%d: NextReader() returned %d, %v", n, op, err)
|
t.Fatalf("%d: NextReader() returned %d, %v", n, op, err)
|
||||||
}
|
}
|
||||||
_, err = io.Copy(io.Discard, r)
|
_, err = io.Copy(ioutil.Discard, r)
|
||||||
if err != errUnexpectedEOF {
|
if err != errUnexpectedEOF {
|
||||||
t.Fatalf("%d: io.Copy() returned %v, want %v", n, err, errUnexpectedEOF)
|
t.Fatalf("%d: io.Copy() returned %v, want %v", n, err, errUnexpectedEOF)
|
||||||
}
|
}
|
||||||
|
@ -425,7 +426,7 @@ func TestEOFBeforeFinalFrame(t *testing.T) {
|
||||||
if op != BinaryMessage || err != nil {
|
if op != BinaryMessage || err != nil {
|
||||||
t.Fatalf("NextReader() returned %d, %v", op, err)
|
t.Fatalf("NextReader() returned %d, %v", op, err)
|
||||||
}
|
}
|
||||||
_, err = io.Copy(io.Discard, r)
|
_, err = io.Copy(ioutil.Discard, r)
|
||||||
if err != errUnexpectedEOF {
|
if err != errUnexpectedEOF {
|
||||||
t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
|
t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
|
||||||
}
|
}
|
||||||
|
@ -489,7 +490,7 @@ func TestReadLimit(t *testing.T) {
|
||||||
if op != BinaryMessage || err != nil {
|
if op != BinaryMessage || err != nil {
|
||||||
t.Fatalf("2: NextReader() returned %d, %v", op, err)
|
t.Fatalf("2: NextReader() returned %d, %v", op, err)
|
||||||
}
|
}
|
||||||
_, err = io.Copy(io.Discard, r)
|
_, err = io.Copy(ioutil.Discard, r)
|
||||||
if err != ErrReadLimit {
|
if err != ErrReadLimit {
|
||||||
t.Fatalf("io.Copy() returned %v", err)
|
t.Fatalf("io.Copy() returned %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ func echoCopyFull(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// echoReadAll echoes messages from the client by reading the entire message
|
// echoReadAll echoes messages from the client by reading the entire message
|
||||||
// with io.ReadAll.
|
// with ioutil.ReadAll.
|
||||||
func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrepared bool) {
|
func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrepared bool) {
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -7,6 +7,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -48,7 +49,7 @@ func readFileIfModified(lastMod time.Time) ([]byte, time.Time, error) {
|
||||||
if !fi.ModTime().After(lastMod) {
|
if !fi.ModTime().After(lastMod) {
|
||||||
return nil, lastMod, nil
|
return nil, lastMod, nil
|
||||||
}
|
}
|
||||||
p, err := os.ReadFile(filename)
|
p, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fi.ModTime(), err
|
return nil, fi.ModTime(), err
|
||||||
}
|
}
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -1,7 +1,3 @@
|
||||||
module github.com/gorilla/websocket
|
module github.com/gorilla/websocket
|
||||||
|
|
||||||
go 1.20
|
go 1.12
|
||||||
|
|
||||||
retract (
|
|
||||||
v1.5.2 // tag accidentally overwritten
|
|
||||||
)
|
|
||||||
|
|
10
server.go
10
server.go
|
@ -172,10 +172,14 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
netConn, brw, err := http.NewResponseController(w).Hijack()
|
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 {
|
if err != nil {
|
||||||
return u.returnError(w, r, http.StatusInternalServerError,
|
return u.returnError(w, r, http.StatusInternalServerError, err.Error())
|
||||||
"websocket: hijack: "+err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if brw.Reader.Buffered() > 0 {
|
if brw.Reader.Buffered() > 0 {
|
||||||
|
|
|
@ -7,10 +7,8 @@ package websocket
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -149,23 +147,3 @@ func TestBufioReuse(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHijack_NotSupported(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
|
||||||
req.Header.Set("Upgrade", "websocket")
|
|
||||||
req.Header.Set("Connection", "upgrade")
|
|
||||||
req.Header.Set("Sec-Websocket-Key", "dGhlIHNhbXBsZSBub25jZQ==")
|
|
||||||
req.Header.Set("Sec-Websocket-Version", "13")
|
|
||||||
|
|
||||||
recorder := httptest.NewRecorder()
|
|
||||||
|
|
||||||
upgrader := Upgrader{}
|
|
||||||
_, err := upgrader.Upgrade(recorder, req, nil)
|
|
||||||
|
|
||||||
if want := (HandshakeError{}); !errors.As(err, &want) || recorder.Code != http.StatusInternalServerError {
|
|
||||||
t.Errorf("want %T and status_code=%d", want, http.StatusInternalServerError)
|
|
||||||
t.Fatalf("got err=%T and status_code=%d", err, recorder.Code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue