diff options
author | Christopher Speller <crspeller@gmail.com> | 2017-06-21 19:06:17 -0700 |
---|---|---|
committer | Corey Hulen <corey@hulen.com> | 2017-06-21 19:06:17 -0700 |
commit | 42f28ab8e374137fe3f5d25424489d879d4724f8 (patch) | |
tree | 20353f2446b506d32e6d353b72a57bf48f070389 /vendor/github.com/gorilla/websocket | |
parent | 6b39c308d882a0aeac533f8ab1d90b48a2ae4b5a (diff) | |
download | chat-42f28ab8e374137fe3f5d25424489d879d4724f8.tar.gz chat-42f28ab8e374137fe3f5d25424489d879d4724f8.tar.bz2 chat-42f28ab8e374137fe3f5d25424489d879d4724f8.zip |
Updating server dependancies (#6712)
Diffstat (limited to 'vendor/github.com/gorilla/websocket')
24 files changed, 147 insertions, 748 deletions
diff --git a/vendor/github.com/gorilla/websocket/.travis.yml b/vendor/github.com/gorilla/websocket/.travis.yml index 3d8d29cf3..4ea1e7a1f 100644 --- a/vendor/github.com/gorilla/websocket/.travis.yml +++ b/vendor/github.com/gorilla/websocket/.travis.yml @@ -7,7 +7,6 @@ matrix: - go: 1.5 - go: 1.6 - go: 1.7 - - go: 1.8 - go: tip allow_failures: - go: tip diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go index 43a87c753..78d932877 100644 --- a/vendor/github.com/gorilla/websocket/client.go +++ b/vendor/github.com/gorilla/websocket/client.go @@ -66,9 +66,8 @@ type Dialer struct { // HandshakeTimeout specifies the duration for the handshake to complete. HandshakeTimeout time.Duration - // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. 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. + // Input and output buffer sizes. If the buffer size is zero, then a + // default value of 4096 is used. ReadBufferSize, WriteBufferSize int // Subprotocols specifies the client's requested subprotocols. @@ -369,7 +368,7 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re return nil, resp, ErrBadHandshake } - for _, ext := range parseExtensions(resp.Header) { + for _, ext := range parseExtensions(req.Header) { if ext[""] != "permessage-deflate" { continue } @@ -390,3 +389,32 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re netConn = nil // to avoid close in defer. return conn, resp, nil } + +// cloneTLSConfig clones all public fields except the fields +// SessionTicketsDisabled and SessionTicketKey. This avoids copying the +// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a +// config in active use. +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return &tls.Config{ + Rand: cfg.Rand, + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + } +} diff --git a/vendor/github.com/gorilla/websocket/client_clone.go b/vendor/github.com/gorilla/websocket/client_clone.go deleted file mode 100644 index 4f0d94372..000000000 --- a/vendor/github.com/gorilla/websocket/client_clone.go +++ /dev/null @@ -1,16 +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. - -// +build go1.8 - -package websocket - -import "crypto/tls" - -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return cfg.Clone() -} diff --git a/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/vendor/github.com/gorilla/websocket/client_clone_legacy.go deleted file mode 100644 index babb007fb..000000000 --- a/vendor/github.com/gorilla/websocket/client_clone_legacy.go +++ /dev/null @@ -1,38 +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. - -// +build !go1.8 - -package websocket - -import "crypto/tls" - -// cloneTLSConfig clones all public fields except the fields -// SessionTicketsDisabled and SessionTicketKey. This avoids copying the -// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a -// config in active use. -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return &tls.Config{ - Rand: cfg.Rand, - Time: cfg.Time, - Certificates: cfg.Certificates, - NameToCertificate: cfg.NameToCertificate, - GetCertificate: cfg.GetCertificate, - RootCAs: cfg.RootCAs, - NextProtos: cfg.NextProtos, - ServerName: cfg.ServerName, - ClientAuth: cfg.ClientAuth, - ClientCAs: cfg.ClientCAs, - InsecureSkipVerify: cfg.InsecureSkipVerify, - CipherSuites: cfg.CipherSuites, - PreferServerCipherSuites: cfg.PreferServerCipherSuites, - ClientSessionCache: cfg.ClientSessionCache, - MinVersion: cfg.MinVersion, - MaxVersion: cfg.MaxVersion, - CurvePreferences: cfg.CurvePreferences, - } -} diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go index 813ffb1e8..72c166b2a 100644 --- a/vendor/github.com/gorilla/websocket/compression.go +++ b/vendor/github.com/gorilla/websocket/compression.go @@ -12,45 +12,31 @@ import ( "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) - }} + flateWriterPool = sync.Pool{} ) -func decompressNoContextTakeover(r io.Reader) io.ReadCloser { +func decompressNoContextTakeover(r io.Reader) io.Reader { 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} + return flate.NewReader(io.MultiReader(r, strings.NewReader(tail))) } -func isValidCompressionLevel(level int) bool { - return minCompressionLevel <= level && level <= maxCompressionLevel -} - -func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { - p := &flateWriterPools[level-minCompressionLevel] +func compressNoContextTakeover(w io.WriteCloser) (io.WriteCloser, error) { tw := &truncWriter{w: w} - fw, _ := p.Get().(*flate.Writer) - if fw == nil { - fw, _ = flate.NewWriter(tw, level) + i := flateWriterPool.Get() + var fw *flate.Writer + var err error + if i == nil { + fw, err = flate.NewWriter(tw, 3) } else { + fw = i.(*flate.Writer) fw.Reset(tw) } - return &flateWriteWrapper{fw: fw, tw: tw, p: p} + return &flateWrapper{fw: fw, tw: tw}, err } // truncWriter is an io.Writer that writes all but the last four bytes of the @@ -89,25 +75,24 @@ func (w *truncWriter) Write(p []byte) (int, error) { return n + nn, err } -type flateWriteWrapper struct { +type flateWrapper struct { fw *flate.Writer tw *truncWriter - p *sync.Pool } -func (w *flateWriteWrapper) Write(p []byte) (int, error) { +func (w *flateWrapper) Write(p []byte) (int, error) { if w.fw == nil { return 0, errWriteClosed } return w.fw.Write(p) } -func (w *flateWriteWrapper) Close() error { +func (w *flateWrapper) Close() error { if w.fw == nil { return errWriteClosed } err1 := w.fw.Flush() - w.p.Put(w.fw) + flateWriterPool.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") @@ -118,31 +103,3 @@ func (w *flateWriteWrapper) Close() error { } 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/compression_test.go b/vendor/github.com/gorilla/websocket/compression_test.go index 659cf4215..cad70fb51 100644 --- a/vendor/github.com/gorilla/websocket/compression_test.go +++ b/vendor/github.com/gorilla/websocket/compression_test.go @@ -2,9 +2,7 @@ package websocket import ( "bytes" - "fmt" "io" - "io/ioutil" "testing" ) @@ -31,50 +29,3 @@ func TestTruncWriter(t *testing.T) { } } } - -func textMessages(num int) [][]byte { - messages := make([][]byte, num) - for i := 0; i < num; i++ { - msg := fmt.Sprintf("planet: %d, country: %d, city: %d, street: %d", i, i, i, i) - messages[i] = []byte(msg) - } - return messages -} - -func BenchmarkWriteNoCompression(b *testing.B) { - w := ioutil.Discard - c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024) - messages := textMessages(100) - b.ResetTimer() - for i := 0; i < b.N; i++ { - c.WriteMessage(TextMessage, messages[i%len(messages)]) - } - b.ReportAllocs() -} - -func BenchmarkWriteWithCompression(b *testing.B) { - w := ioutil.Discard - c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024) - messages := textMessages(100) - c.enableWriteCompression = true - c.newCompressionWriter = compressNoContextTakeover - b.ResetTimer() - for i := 0; i < b.N; i++ { - c.WriteMessage(TextMessage, messages[i%len(messages)]) - } - b.ReportAllocs() -} - -func TestValidCompressionLevel(t *testing.T) { - c := newConn(fakeNetConn{}, false, 1024, 1024) - for _, level := range []int{minCompressionLevel - 1, maxCompressionLevel + 1} { - if err := c.SetCompressionLevel(level); err == nil { - t.Errorf("no error for level %d", level) - } - } - for _, level := range []int{minCompressionLevel, maxCompressionLevel} { - if err := c.SetCompressionLevel(level); err != nil { - t.Errorf("error for level %d", level) - } - } -} diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go index 97e1dbacb..ce7f0a615 100644 --- a/vendor/github.com/gorilla/websocket/conn.go +++ b/vendor/github.com/gorilla/websocket/conn.go @@ -10,7 +10,6 @@ import ( "errors" "io" "io/ioutil" - "math/rand" "net" "strconv" "sync" @@ -181,11 +180,6 @@ var ( 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()} @@ -241,11 +235,9 @@ type Conn struct { writeErr error enableWriteCompression bool - compressionLevel int - newCompressionWriter func(io.WriteCloser, int) io.WriteCloser + newCompressionWriter func(io.WriteCloser) (io.WriteCloser, error) // Read fields - reader io.ReadCloser // the current reader returned to the application readErr error br *bufio.Reader readRemaining int64 // bytes remaining in current frame. @@ -261,76 +253,31 @@ type Conn struct { messageReader *messageReader // the current low-level reader readDecompress bool // whether last read frame had RSV1 set - newDecompressionReader func(io.Reader) io.ReadCloser + newDecompressionReader func(io.Reader) io.Reader } func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn { - return newConnBRW(conn, isServer, readBufferSize, writeBufferSize, nil) -} - -type writeHook struct { - p []byte -} - -func (wh *writeHook) Write(p []byte) (int, error) { - wh.p = p - return len(p), nil -} - -func newConnBRW(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, brw *bufio.ReadWriter) *Conn { mu := make(chan bool, 1) mu <- true - var br *bufio.Reader - if readBufferSize == 0 && brw != nil && brw.Reader != nil { - // Reuse the supplied bufio.Reader if the buffer has a useful size. - // This code assumes that peek on a reader returns - // bufio.Reader.buf[:0]. - brw.Reader.Reset(conn) - if p, err := brw.Reader.Peek(0); err == nil && cap(p) >= 256 { - br = brw.Reader - } + if readBufferSize == 0 { + readBufferSize = defaultReadBufferSize } - if br == nil { - if readBufferSize == 0 { - readBufferSize = defaultReadBufferSize - } - if readBufferSize < maxControlFramePayloadSize { - readBufferSize = maxControlFramePayloadSize - } - br = bufio.NewReaderSize(conn, readBufferSize) - } - - var writeBuf []byte - if writeBufferSize == 0 && brw != nil && brw.Writer != nil { - // Use the bufio.Writer's buffer if the buffer has a useful size. This - // code assumes that bufio.Writer.buf[:1] is passed to the - // bufio.Writer's underlying writer. - var wh writeHook - brw.Writer.Reset(&wh) - brw.Writer.WriteByte(0) - brw.Flush() - if cap(wh.p) >= maxFrameHeaderSize+256 { - writeBuf = wh.p[:cap(wh.p)] - } + if readBufferSize < maxControlFramePayloadSize { + readBufferSize = maxControlFramePayloadSize } - - if writeBuf == nil { - if writeBufferSize == 0 { - writeBufferSize = defaultWriteBufferSize - } - writeBuf = make([]byte, writeBufferSize+maxFrameHeaderSize) + if writeBufferSize == 0 { + writeBufferSize = defaultWriteBufferSize } c := &Conn{ isServer: isServer, - br: br, + br: bufio.NewReaderSize(conn, readBufferSize), conn: conn, mu: mu, readFinal: true, - writeBuf: writeBuf, + writeBuf: make([]byte, writeBufferSize+maxFrameHeaderSize), enableWriteCompression: true, - compressionLevel: defaultCompressionLevel, } c.SetCloseHandler(nil) c.SetPingHandler(nil) @@ -496,7 +443,11 @@ func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { } c.writer = mw if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) { - w := c.newCompressionWriter(c.writer, c.compressionLevel) + w, err := c.newCompressionWriter(c.writer) + if err != nil { + c.writer = nil + return nil, err + } mw.compress = true c.writer = w } @@ -703,33 +654,12 @@ func (w *messageWriter) Close() error { return 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. if err := c.prepWrite(messageType); err != nil { @@ -925,11 +855,6 @@ func (c *Conn) handleProtocolError(message string) error { // 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 @@ -942,11 +867,11 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { } if frameType == TextMessage || frameType == BinaryMessage { c.messageReader = &messageReader{c} - c.reader = c.messageReader + var r io.Reader = c.messageReader if c.readDecompress { - c.reader = c.newDecompressionReader(c.reader) + r = c.newDecompressionReader(r) } - return frameType, c.reader, nil + return frameType, r, nil } } @@ -1008,10 +933,6 @@ func (r *messageReader) Read(b []byte) (int, error) { 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) { @@ -1048,15 +969,6 @@ func (c *Conn) CloseHandler() func(code int, text string) error { // 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 frame // back to the peer. -// -// The application must read the connection to process close messages as -// described in the section on Control Frames above. -// -// The connection read methods return a CloseError when a close frame 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 frame 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 { @@ -1079,9 +991,6 @@ func (c *Conn) PingHandler() func(appData string) error { // SetPingHandler sets the handler for ping messages received from the peer. // The appData argument to h is the PING frame application data. The default // ping handler sends a pong to the peer. -// -// The application must read the connection to process ping messages as -// described in the section on Control Frames above. func (c *Conn) SetPingHandler(h func(appData string) error) { if h == nil { h = func(message string) error { @@ -1105,9 +1014,6 @@ func (c *Conn) PongHandler() func(appData string) error { // SetPongHandler sets the handler for pong messages received from the peer. // The appData argument to h is the PONG frame application data. The default // pong handler does nothing. -// -// The application must read the connection to process ping messages as -// described in the section on Control Frames above. func (c *Conn) SetPongHandler(h func(appData string) error) { if h == nil { h = func(string) error { return nil } @@ -1128,18 +1034,6 @@ 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. func FormatCloseMessage(closeCode int, text string) []byte { buf := make([]byte, 2+len(text)) diff --git a/vendor/github.com/gorilla/websocket/conn_broadcast_test.go b/vendor/github.com/gorilla/websocket/conn_broadcast_test.go deleted file mode 100644 index 45038e488..000000000 --- a/vendor/github.com/gorilla/websocket/conn_broadcast_test.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.7 - -package websocket - -import ( - "io" - "io/ioutil" - "sync/atomic" - "testing" -) - -// broadcastBench allows to run broadcast benchmarks. -// In every broadcast benchmark we create many connections, then send the same -// message into every connection and wait for all writes complete. This emulates -// an application where many connections listen to the same data - i.e. PUB/SUB -// scenarios with many subscribers in one channel. -type broadcastBench struct { - w io.Writer - message *broadcastMessage - closeCh chan struct{} - doneCh chan struct{} - count int32 - conns []*broadcastConn - compression bool - usePrepared bool -} - -type broadcastMessage struct { - payload []byte - prepared *PreparedMessage -} - -type broadcastConn struct { - conn *Conn - msgCh chan *broadcastMessage -} - -func newBroadcastConn(c *Conn) *broadcastConn { - return &broadcastConn{ - conn: c, - msgCh: make(chan *broadcastMessage, 1), - } -} - -func newBroadcastBench(usePrepared, compression bool) *broadcastBench { - bench := &broadcastBench{ - w: ioutil.Discard, - doneCh: make(chan struct{}), - closeCh: make(chan struct{}), - usePrepared: usePrepared, - compression: compression, - } - msg := &broadcastMessage{ - payload: textMessages(1)[0], - } - if usePrepared { - pm, _ := NewPreparedMessage(TextMessage, msg.payload) - msg.prepared = pm - } - bench.message = msg - bench.makeConns(10000) - return bench -} - -func (b *broadcastBench) makeConns(numConns int) { - conns := make([]*broadcastConn, numConns) - - for i := 0; i < numConns; i++ { - c := newConn(fakeNetConn{Reader: nil, Writer: b.w}, true, 1024, 1024) - if b.compression { - c.enableWriteCompression = true - c.newCompressionWriter = compressNoContextTakeover - } - conns[i] = newBroadcastConn(c) - go func(c *broadcastConn) { - for { - select { - case msg := <-c.msgCh: - if b.usePrepared { - c.conn.WritePreparedMessage(msg.prepared) - } else { - c.conn.WriteMessage(TextMessage, msg.payload) - } - val := atomic.AddInt32(&b.count, 1) - if val%int32(numConns) == 0 { - b.doneCh <- struct{}{} - } - case <-b.closeCh: - return - } - } - }(conns[i]) - } - b.conns = conns -} - -func (b *broadcastBench) close() { - close(b.closeCh) -} - -func (b *broadcastBench) runOnce() { - for _, c := range b.conns { - c.msgCh <- b.message - } - <-b.doneCh -} - -func BenchmarkBroadcast(b *testing.B) { - benchmarks := []struct { - name string - usePrepared bool - compression bool - }{ - {"NoCompression", false, false}, - {"WithCompression", false, true}, - {"NoCompressionPrepared", true, false}, - {"WithCompressionPrepared", true, true}, - } - for _, bm := range benchmarks { - b.Run(bm.name, func(b *testing.B) { - bench := newBroadcastBench(bm.usePrepared, bm.compression) - defer bench.close() - b.ResetTimer() - for i := 0; i < b.N; i++ { - bench.runOnce() - } - b.ReportAllocs() - }) - } -} diff --git a/vendor/github.com/gorilla/websocket/conn_test.go b/vendor/github.com/gorilla/websocket/conn_test.go index 06e9bc3f5..7431383b1 100644 --- a/vendor/github.com/gorilla/websocket/conn_test.go +++ b/vendor/github.com/gorilla/websocket/conn_test.go @@ -463,35 +463,3 @@ func TestFailedConnectionReadPanic(t *testing.T) { } t.Fatal("should not get here") } - -func TestBufioReuse(t *testing.T) { - brw := bufio.NewReadWriter(bufio.NewReader(nil), bufio.NewWriter(nil)) - c := newConnBRW(nil, false, 0, 0, brw) - - if c.br != brw.Reader { - t.Error("connection did not reuse bufio.Reader") - } - - var wh writeHook - brw.Writer.Reset(&wh) - brw.WriteByte(0) - brw.Flush() - if &c.writeBuf[0] != &wh.p[0] { - t.Error("connection did not reuse bufio.Writer") - } - - brw = bufio.NewReadWriter(bufio.NewReaderSize(nil, 0), bufio.NewWriterSize(nil, 0)) - c = newConnBRW(nil, false, 0, 0, brw) - - if c.br == brw.Reader { - t.Error("connection used bufio.Reader with small size") - } - - brw.Writer.Reset(&wh) - brw.WriteByte(0) - brw.Flush() - if &c.writeBuf[0] != &wh.p[0] { - t.Error("connection used bufio.Writer with small size") - } - -} diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go index e291a952c..610acf712 100644 --- a/vendor/github.com/gorilla/websocket/doc.go +++ b/vendor/github.com/gorilla/websocket/doc.go @@ -118,10 +118,9 @@ // // 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. +// WriteJSON) 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. @@ -151,25 +150,19 @@ // application's responsibility to check the Origin header before calling // Upgrade. // -// Compression EXPERIMENTAL +// 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. +// support. 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) +// conn.EnableWriteCompression(true) // // Currently this package does not support compression with "context takeover". // This means that messages must be compressed and decompressed in isolation, diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json b/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json index aa3a0bc0a..27d5a5b14 100644 --- a/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json +++ b/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json @@ -4,7 +4,6 @@ "outdir": "./reports/clients", "servers": [ {"agent": "ReadAllWriteMessage", "url": "ws://localhost:9000/m", "options": {"version": 18}}, - {"agent": "ReadAllWritePreparedMessage", "url": "ws://localhost:9000/p", "options": {"version": 18}}, {"agent": "ReadAllWrite", "url": "ws://localhost:9000/r", "options": {"version": 18}}, {"agent": "CopyFull", "url": "ws://localhost:9000/f", "options": {"version": 18}}, {"agent": "CopyWriterOnly", "url": "ws://localhost:9000/c", "options": {"version": 18}} diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/server.go b/vendor/github.com/gorilla/websocket/examples/autobahn/server.go index 3db880f90..e98563be9 100644 --- a/vendor/github.com/gorilla/websocket/examples/autobahn/server.go +++ b/vendor/github.com/gorilla/websocket/examples/autobahn/server.go @@ -85,7 +85,7 @@ func echoCopyFull(w http.ResponseWriter, r *http.Request) { // echoReadAll echoes messages from the client by reading the entire message // with ioutil.ReadAll. -func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrepared bool) { +func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage bool) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println("Upgrade:", err) @@ -109,21 +109,9 @@ func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrep } } if writeMessage { - if !writePrepared { - err = conn.WriteMessage(mt, b) - if err != nil { - log.Println("WriteMessage:", err) - } - } else { - pm, err := websocket.NewPreparedMessage(mt, b) - if err != nil { - log.Println("NewPreparedMessage:", err) - return - } - err = conn.WritePreparedMessage(pm) - if err != nil { - log.Println("WritePreparedMessage:", err) - } + err = conn.WriteMessage(mt, b) + if err != nil { + log.Println("WriteMessage:", err) } } else { w, err := conn.NextWriter(mt) @@ -144,15 +132,11 @@ func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrep } func echoReadAllWriter(w http.ResponseWriter, r *http.Request) { - echoReadAll(w, r, false, false) + echoReadAll(w, r, false) } func echoReadAllWriteMessage(w http.ResponseWriter, r *http.Request) { - echoReadAll(w, r, true, false) -} - -func echoReadAllWritePreparedMessage(w http.ResponseWriter, r *http.Request) { - echoReadAll(w, r, true, true) + echoReadAll(w, r, true) } func serveHome(w http.ResponseWriter, r *http.Request) { @@ -177,7 +161,6 @@ func main() { http.HandleFunc("/f", echoCopyFull) http.HandleFunc("/r", echoReadAllWriter) http.HandleFunc("/m", echoReadAllWriteMessage) - http.HandleFunc("/p", echoReadAllWritePreparedMessage) err := http.ListenAndServe(*addr, nil) if err != nil { log.Fatal("ListenAndServe: ", err) diff --git a/vendor/github.com/gorilla/websocket/examples/chat/home.html b/vendor/github.com/gorilla/websocket/examples/chat/home.html index a39a0c276..7262918ec 100644 --- a/vendor/github.com/gorilla/websocket/examples/chat/home.html +++ b/vendor/github.com/gorilla/websocket/examples/chat/home.html @@ -9,7 +9,7 @@ window.onload = function () { var log = document.getElementById("log"); function appendLog(item) { - var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1; + var doScroll = log.scrollTop === log.scrollHeight - log.clientHeight; log.appendChild(item); if (doScroll) { log.scrollTop = log.scrollHeight - log.clientHeight; @@ -29,7 +29,7 @@ window.onload = function () { }; if (window["WebSocket"]) { - conn = new WebSocket("ws://" + document.location.host + "/ws"); + conn = new WebSocket("ws://{{$}}/ws"); conn.onclose = function (evt) { var item = document.createElement("div"); item.innerHTML = "<b>Connection closed.</b>"; diff --git a/vendor/github.com/gorilla/websocket/examples/chat/main.go b/vendor/github.com/gorilla/websocket/examples/chat/main.go index 74615d59c..a865ffec5 100644 --- a/vendor/github.com/gorilla/websocket/examples/chat/main.go +++ b/vendor/github.com/gorilla/websocket/examples/chat/main.go @@ -8,9 +8,11 @@ import ( "flag" "log" "net/http" + "text/template" ) var addr = flag.String("addr", ":8080", "http service address") +var homeTemplate = template.Must(template.ParseFiles("home.html")) func serveHome(w http.ResponseWriter, r *http.Request) { log.Println(r.URL) @@ -22,7 +24,8 @@ func serveHome(w http.ResponseWriter, r *http.Request) { http.Error(w, "Method not allowed", 405) return } - http.ServeFile(w, r, "home.html") + w.Header().Set("Content-Type", "text/html; charset=utf-8") + homeTemplate.Execute(w, r.Host) } func main() { diff --git a/vendor/github.com/gorilla/websocket/examples/command/README.md b/vendor/github.com/gorilla/websocket/examples/command/README.md index ed6f78684..c30d3979a 100644 --- a/vendor/github.com/gorilla/websocket/examples/command/README.md +++ b/vendor/github.com/gorilla/websocket/examples/command/README.md @@ -2,7 +2,7 @@ This example connects a websocket connection to stdin and stdout of a command. Received messages are written to stdin followed by a `\n`. Each line read from -standard out is sent as a message to the client. +from standard out is sent as a message to the client. $ go get github.com/gorilla/websocket $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/command` diff --git a/vendor/github.com/gorilla/websocket/examples/command/home.html b/vendor/github.com/gorilla/websocket/examples/command/home.html index 19c46128a..72fd02b2a 100644 --- a/vendor/github.com/gorilla/websocket/examples/command/home.html +++ b/vendor/github.com/gorilla/websocket/examples/command/home.html @@ -2,53 +2,47 @@ <html lang="en"> <head> <title>Command Example</title> +<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script type="text/javascript"> -window.onload = function () { + $(function() { + var conn; - var msg = document.getElementById("msg"); - var log = document.getElementById("log"); + var msg = $("#msg"); + var log = $("#log"); - function appendLog(item) { - var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1; - log.appendChild(item); + function appendLog(msg) { + var d = log[0] + var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight; + msg.appendTo(log) if (doScroll) { - log.scrollTop = log.scrollHeight - log.clientHeight; + d.scrollTop = d.scrollHeight - d.clientHeight; } } - document.getElementById("form").onsubmit = function () { + $("#form").submit(function() { if (!conn) { return false; } - if (!msg.value) { + if (!msg.val()) { return false; } - conn.send(msg.value); - msg.value = ""; - return false; - }; + conn.send(msg.val()); + msg.val(""); + return false + }); if (window["WebSocket"]) { - conn = new WebSocket("ws://" + document.location.host + "/ws"); - conn.onclose = function (evt) { - var item = document.createElement("div"); - item.innerHTML = "<b>Connection closed.</b>"; - appendLog(item); - }; - conn.onmessage = function (evt) { - var messages = evt.data.split('\n'); - for (var i = 0; i < messages.length; i++) { - var item = document.createElement("div"); - item.innerText = messages[i]; - appendLog(item); - } - }; + conn = new WebSocket("ws://{{$}}/ws"); + conn.onclose = function(evt) { + appendLog($("<div><b>Connection closed.</b></div>")) + } + conn.onmessage = function(evt) { + appendLog($("<pre/>").text(evt.data)) + } } else { - var item = document.createElement("div"); - item.innerHTML = "<b>Your browser does not support WebSockets.</b>"; - appendLog(item); + appendLog($("<div><b>Your browser does not support WebSockets.</b></div>")) } -}; + }); </script> <style type="text/css"> html { diff --git a/vendor/github.com/gorilla/websocket/examples/command/main.go b/vendor/github.com/gorilla/websocket/examples/command/main.go index 239c5c85c..438fb8328 100644 --- a/vendor/github.com/gorilla/websocket/examples/command/main.go +++ b/vendor/github.com/gorilla/websocket/examples/command/main.go @@ -12,14 +12,16 @@ import ( "net/http" "os" "os/exec" + "text/template" "time" "github.com/gorilla/websocket" ) var ( - addr = flag.String("addr", "127.0.0.1:8080", "http service address") - cmdPath string + addr = flag.String("addr", "127.0.0.1:8080", "http service address") + cmdPath string + homeTempl = template.Must(template.ParseFiles("home.html")) ) const ( @@ -174,7 +176,8 @@ func serveHome(w http.ResponseWriter, r *http.Request) { http.Error(w, "Method not allowed", 405) return } - http.ServeFile(w, r, "home.html") + w.Header().Set("Content-Type", "text/html; charset=utf-8") + homeTempl.Execute(w, r.Host) } func main() { diff --git a/vendor/github.com/gorilla/websocket/examples/filewatch/main.go b/vendor/github.com/gorilla/websocket/examples/filewatch/main.go index f5f9da5c3..2ac2b324f 100644 --- a/vendor/github.com/gorilla/websocket/examples/filewatch/main.go +++ b/vendor/github.com/gorilla/websocket/examples/filewatch/main.go @@ -6,12 +6,12 @@ package main import ( "flag" - "html/template" "io/ioutil" "log" "net/http" "os" "strconv" + "text/template" "time" "github.com/gorilla/websocket" diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go index 6a88bbc74..6758a2cb7 100644 --- a/vendor/github.com/gorilla/websocket/mask.go +++ b/vendor/github.com/gorilla/websocket/mask.go @@ -2,14 +2,20 @@ // this source code is governed by a BSD-style license that can be found in the // LICENSE file. -// +build !appengine - package websocket -import "unsafe" +import ( + "math/rand" + "unsafe" +) const wordSize = int(unsafe.Sizeof(uintptr(0))) +func newMaskKey() [4]byte { + n := rand.Uint32() + return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} +} + func maskBytes(key [4]byte, pos int, b []byte) int { // Mask one byte at a time for small buffers. 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 2aac060e5..000000000 --- a/vendor/github.com/gorilla/websocket/mask_safe.go +++ /dev/null @@ -1,15 +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. - -// +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/mask_test.go b/vendor/github.com/gorilla/websocket/mask_test.go index 298a1e509..de0602993 100644 --- a/vendor/github.com/gorilla/websocket/mask_test.go +++ b/vendor/github.com/gorilla/websocket/mask_test.go @@ -3,7 +3,7 @@ // LICENSE file. // Require 1.7 for sub-bencmarks -// +build go1.7,!appengine +// +build go1.7 package websocket diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go deleted file mode 100644 index 1efffbd1e..000000000 --- a/vendor/github.com/gorilla/websocket/prepared.go +++ /dev/null @@ -1,103 +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 - err error - 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 bool, 1) - mu <- true - 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/prepared_test.go b/vendor/github.com/gorilla/websocket/prepared_test.go deleted file mode 100644 index cf98c6c10..000000000 --- a/vendor/github.com/gorilla/websocket/prepared_test.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bytes" - "compress/flate" - "math/rand" - "testing" -) - -var preparedMessageTests = []struct { - messageType int - isServer bool - enableWriteCompression bool - compressionLevel int -}{ - // Server - {TextMessage, true, false, flate.BestSpeed}, - {TextMessage, true, true, flate.BestSpeed}, - {TextMessage, true, true, flate.BestCompression}, - {PingMessage, true, false, flate.BestSpeed}, - {PingMessage, true, true, flate.BestSpeed}, - - // Client - {TextMessage, false, false, flate.BestSpeed}, - {TextMessage, false, true, flate.BestSpeed}, - {TextMessage, false, true, flate.BestCompression}, - {PingMessage, false, false, flate.BestSpeed}, - {PingMessage, false, true, flate.BestSpeed}, -} - -func TestPreparedMessage(t *testing.T) { - for _, tt := range preparedMessageTests { - var data = []byte("this is a test") - var buf bytes.Buffer - c := newConn(fakeNetConn{Reader: nil, Writer: &buf}, tt.isServer, 1024, 1024) - if tt.enableWriteCompression { - c.newCompressionWriter = compressNoContextTakeover - } - c.SetCompressionLevel(tt.compressionLevel) - - // Seed random number generator for consistent frame mask. - rand.Seed(1234) - - if err := c.WriteMessage(tt.messageType, data); err != nil { - t.Fatal(err) - } - want := buf.String() - - pm, err := NewPreparedMessage(tt.messageType, data) - if err != nil { - t.Fatal(err) - } - - // Scribble on data to ensure that NewPreparedMessage takes a snapshot. - copy(data, "hello world") - - // Seed random number generator for consistent frame mask. - rand.Seed(1234) - - buf.Reset() - if err := c.WritePreparedMessage(pm); err != nil { - t.Fatal(err) - } - got := buf.String() - - if got != want { - t.Errorf("write message != prepared message for %+v", tt) - } - } -} diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go index 3495e0f1a..aaedebdbe 100644 --- a/vendor/github.com/gorilla/websocket/server.go +++ b/vendor/github.com/gorilla/websocket/server.go @@ -28,9 +28,8 @@ type Upgrader struct { HandshakeTimeout time.Duration // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. 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. + // size is zero, then a default value of 4096 is used. The I/O buffer sizes + // do not limit the size of the messages that can be sent or received. ReadBufferSize, WriteBufferSize int // Subprotocols specifies the server's supported protocols in order of @@ -105,23 +104,23 @@ func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header // response. func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { if r.Method != "GET" { - return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: not a websocket handshake: request method is not GET") + return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: method not GET") } if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { - return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-Websocket-Extensions' headers are unsupported") + return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific Sec-Websocket-Extensions headers are unsupported") } - if !tokenListContainsValue(r.Header, "Connection", "upgrade") { - return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'upgrade' token not found in 'Connection' header") + if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: version != 13") } - if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { - return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'websocket' token not found in 'Upgrade' header") + if !tokenListContainsValue(r.Header, "Connection", "upgrade") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find connection header with token 'upgrade'") } - 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 !tokenListContainsValue(r.Header, "Upgrade", "websocket") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find upgrade header with token 'websocket'") } checkOrigin := u.CheckOrigin @@ -129,12 +128,12 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade checkOrigin = checkSameOrigin } if !checkOrigin(r) { - return u.returnError(w, r, http.StatusForbidden, "websocket: 'Origin' header value not allowed") + return u.returnError(w, r, http.StatusForbidden, "websocket: origin not allowed") } challengeKey := r.Header.Get("Sec-Websocket-Key") if challengeKey == "" { - return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-Websocket-Key' header is missing or blank") + return u.returnError(w, r, http.StatusBadRequest, "websocket: key missing or blank") } subprotocol := u.selectSubprotocol(r, responseHeader) @@ -153,6 +152,7 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade var ( netConn net.Conn + br *bufio.Reader err error ) @@ -160,18 +160,19 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade 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() + var rw *bufio.ReadWriter + netConn, rw, err = h.Hijack() if err != nil { return u.returnError(w, r, http.StatusInternalServerError, err.Error()) } + br = rw.Reader - if brw.Reader.Buffered() > 0 { + if br.Buffered() > 0 { netConn.Close() return nil, errors.New("websocket: client sent data before handshake is complete") } - c := newConnBRW(netConn, true, u.ReadBufferSize, u.WriteBufferSize, brw) + c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize) c.subprotocol = subprotocol if compress { |