···11+# This is the official list of Gorilla WebSocket authors for copyright
22+# purposes.
33+#
44+# Please keep the list sorted.
55+66+Gary Burd <gary@beagledreams.com>
77+Google LLC (https://opensource.google.com/)
88+Joachim Bauch <mail@joachim-bauch.de>
99+
+22
vendor/github.com/gorilla/websocket/LICENSE
···11+Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved.
22+33+Redistribution and use in source and binary forms, with or without
44+modification, are permitted provided that the following conditions are met:
55+66+ Redistributions of source code must retain the above copyright notice, this
77+ list of conditions and the following disclaimer.
88+99+ Redistributions in binary form must reproduce the above copyright notice,
1010+ this list of conditions and the following disclaimer in the documentation
1111+ and/or other materials provided with the distribution.
1212+1313+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1414+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1515+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1616+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
1717+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1818+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1919+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2020+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2121+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2222+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+33
vendor/github.com/gorilla/websocket/README.md
···11+# Gorilla WebSocket
22+33+[](https://godoc.org/github.com/gorilla/websocket)
44+[](https://circleci.com/gh/gorilla/websocket)
55+66+Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
77+[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
88+99+1010+### Documentation
1111+1212+* [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc)
1313+* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
1414+* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
1515+* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
1616+* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
1717+1818+### Status
1919+2020+The Gorilla WebSocket package provides a complete and tested implementation of
2121+the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
2222+package API is stable.
2323+2424+### Installation
2525+2626+ go get github.com/gorilla/websocket
2727+2828+### Protocol Compliance
2929+3030+The Gorilla WebSocket package passes the server tests in the [Autobahn Test
3131+Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn
3232+subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
3333+
+434
vendor/github.com/gorilla/websocket/client.go
···11+// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "bytes"
99+ "context"
1010+ "crypto/tls"
1111+ "errors"
1212+ "fmt"
1313+ "io"
1414+ "io/ioutil"
1515+ "net"
1616+ "net/http"
1717+ "net/http/httptrace"
1818+ "net/url"
1919+ "strings"
2020+ "time"
2121+)
2222+2323+// ErrBadHandshake is returned when the server response to opening handshake is
2424+// invalid.
2525+var ErrBadHandshake = errors.New("websocket: bad handshake")
2626+2727+var errInvalidCompression = errors.New("websocket: invalid compression negotiation")
2828+2929+// NewClient creates a new client connection using the given net connection.
3030+// The URL u specifies the host and request URI. Use requestHeader to specify
3131+// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
3232+// (Cookie). Use the response.Header to get the selected subprotocol
3333+// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
3434+//
3535+// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
3636+// non-nil *http.Response so that callers can handle redirects, authentication,
3737+// etc.
3838+//
3939+// Deprecated: Use Dialer instead.
4040+func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
4141+ d := Dialer{
4242+ ReadBufferSize: readBufSize,
4343+ WriteBufferSize: writeBufSize,
4444+ NetDial: func(net, addr string) (net.Conn, error) {
4545+ return netConn, nil
4646+ },
4747+ }
4848+ return d.Dial(u.String(), requestHeader)
4949+}
5050+5151+// A Dialer contains options for connecting to WebSocket server.
5252+//
5353+// It is safe to call Dialer's methods concurrently.
5454+type Dialer struct {
5555+ // NetDial specifies the dial function for creating TCP connections. If
5656+ // NetDial is nil, net.Dial is used.
5757+ NetDial func(network, addr string) (net.Conn, error)
5858+5959+ // NetDialContext specifies the dial function for creating TCP connections. If
6060+ // NetDialContext is nil, NetDial is used.
6161+ NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)
6262+6363+ // NetDialTLSContext specifies the dial function for creating TLS/TCP connections. If
6464+ // NetDialTLSContext is nil, NetDialContext is used.
6565+ // If NetDialTLSContext is set, Dial assumes the TLS handshake is done there and
6666+ // TLSClientConfig is ignored.
6767+ NetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
6868+6969+ // Proxy specifies a function to return a proxy for a given
7070+ // Request. If the function returns a non-nil error, the
7171+ // request is aborted with the provided error.
7272+ // If Proxy is nil or returns a nil *URL, no proxy is used.
7373+ Proxy func(*http.Request) (*url.URL, error)
7474+7575+ // TLSClientConfig specifies the TLS configuration to use with tls.Client.
7676+ // If nil, the default configuration is used.
7777+ // If either NetDialTLS or NetDialTLSContext are set, Dial assumes the TLS handshake
7878+ // is done there and TLSClientConfig is ignored.
7979+ TLSClientConfig *tls.Config
8080+8181+ // HandshakeTimeout specifies the duration for the handshake to complete.
8282+ HandshakeTimeout time.Duration
8383+8484+ // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer
8585+ // size is zero, then a useful default size is used. The I/O buffer sizes
8686+ // do not limit the size of the messages that can be sent or received.
8787+ ReadBufferSize, WriteBufferSize int
8888+8989+ // WriteBufferPool is a pool of buffers for write operations. If the value
9090+ // is not set, then write buffers are allocated to the connection for the
9191+ // lifetime of the connection.
9292+ //
9393+ // A pool is most useful when the application has a modest volume of writes
9494+ // across a large number of connections.
9595+ //
9696+ // Applications should use a single pool for each unique value of
9797+ // WriteBufferSize.
9898+ WriteBufferPool BufferPool
9999+100100+ // Subprotocols specifies the client's requested subprotocols.
101101+ Subprotocols []string
102102+103103+ // EnableCompression specifies if the client should attempt to negotiate
104104+ // per message compression (RFC 7692). Setting this value to true does not
105105+ // guarantee that compression will be supported. Currently only "no context
106106+ // takeover" modes are supported.
107107+ EnableCompression bool
108108+109109+ // Jar specifies the cookie jar.
110110+ // If Jar is nil, cookies are not sent in requests and ignored
111111+ // in responses.
112112+ Jar http.CookieJar
113113+}
114114+115115+// Dial creates a new client connection by calling DialContext with a background context.
116116+func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
117117+ return d.DialContext(context.Background(), urlStr, requestHeader)
118118+}
119119+120120+var errMalformedURL = errors.New("malformed ws or wss URL")
121121+122122+func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
123123+ hostPort = u.Host
124124+ hostNoPort = u.Host
125125+ if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
126126+ hostNoPort = hostNoPort[:i]
127127+ } else {
128128+ switch u.Scheme {
129129+ case "wss":
130130+ hostPort += ":443"
131131+ case "https":
132132+ hostPort += ":443"
133133+ default:
134134+ hostPort += ":80"
135135+ }
136136+ }
137137+ return hostPort, hostNoPort
138138+}
139139+140140+// DefaultDialer is a dialer with all fields set to the default values.
141141+var DefaultDialer = &Dialer{
142142+ Proxy: http.ProxyFromEnvironment,
143143+ HandshakeTimeout: 45 * time.Second,
144144+}
145145+146146+// nilDialer is dialer to use when receiver is nil.
147147+var nilDialer = *DefaultDialer
148148+149149+// DialContext creates a new client connection. Use requestHeader to specify the
150150+// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
151151+// Use the response.Header to get the selected subprotocol
152152+// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
153153+//
154154+// The context will be used in the request and in the Dialer.
155155+//
156156+// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
157157+// non-nil *http.Response so that callers can handle redirects, authentication,
158158+// etcetera. The response body may not contain the entire response and does not
159159+// need to be closed by the application.
160160+func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
161161+ if d == nil {
162162+ d = &nilDialer
163163+ }
164164+165165+ challengeKey, err := generateChallengeKey()
166166+ if err != nil {
167167+ return nil, nil, err
168168+ }
169169+170170+ u, err := url.Parse(urlStr)
171171+ if err != nil {
172172+ return nil, nil, err
173173+ }
174174+175175+ switch u.Scheme {
176176+ case "ws":
177177+ u.Scheme = "http"
178178+ case "wss":
179179+ u.Scheme = "https"
180180+ default:
181181+ return nil, nil, errMalformedURL
182182+ }
183183+184184+ if u.User != nil {
185185+ // User name and password are not allowed in websocket URIs.
186186+ return nil, nil, errMalformedURL
187187+ }
188188+189189+ req := &http.Request{
190190+ Method: http.MethodGet,
191191+ URL: u,
192192+ Proto: "HTTP/1.1",
193193+ ProtoMajor: 1,
194194+ ProtoMinor: 1,
195195+ Header: make(http.Header),
196196+ Host: u.Host,
197197+ }
198198+ req = req.WithContext(ctx)
199199+200200+ // Set the cookies present in the cookie jar of the dialer
201201+ if d.Jar != nil {
202202+ for _, cookie := range d.Jar.Cookies(u) {
203203+ req.AddCookie(cookie)
204204+ }
205205+ }
206206+207207+ // Set the request headers using the capitalization for names and values in
208208+ // RFC examples. Although the capitalization shouldn't matter, there are
209209+ // servers that depend on it. The Header.Set method is not used because the
210210+ // method canonicalizes the header names.
211211+ req.Header["Upgrade"] = []string{"websocket"}
212212+ req.Header["Connection"] = []string{"Upgrade"}
213213+ req.Header["Sec-WebSocket-Key"] = []string{challengeKey}
214214+ req.Header["Sec-WebSocket-Version"] = []string{"13"}
215215+ if len(d.Subprotocols) > 0 {
216216+ req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")}
217217+ }
218218+ for k, vs := range requestHeader {
219219+ switch {
220220+ case k == "Host":
221221+ if len(vs) > 0 {
222222+ req.Host = vs[0]
223223+ }
224224+ case k == "Upgrade" ||
225225+ k == "Connection" ||
226226+ k == "Sec-Websocket-Key" ||
227227+ k == "Sec-Websocket-Version" ||
228228+ k == "Sec-Websocket-Extensions" ||
229229+ (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
230230+ return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
231231+ case k == "Sec-Websocket-Protocol":
232232+ req.Header["Sec-WebSocket-Protocol"] = vs
233233+ default:
234234+ req.Header[k] = vs
235235+ }
236236+ }
237237+238238+ if d.EnableCompression {
239239+ req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"}
240240+ }
241241+242242+ if d.HandshakeTimeout != 0 {
243243+ var cancel func()
244244+ ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout)
245245+ defer cancel()
246246+ }
247247+248248+ // Get network dial function.
249249+ var netDial func(network, add string) (net.Conn, error)
250250+251251+ switch u.Scheme {
252252+ case "http":
253253+ if d.NetDialContext != nil {
254254+ netDial = func(network, addr string) (net.Conn, error) {
255255+ return d.NetDialContext(ctx, network, addr)
256256+ }
257257+ } else if d.NetDial != nil {
258258+ netDial = d.NetDial
259259+ }
260260+ case "https":
261261+ if d.NetDialTLSContext != nil {
262262+ netDial = func(network, addr string) (net.Conn, error) {
263263+ return d.NetDialTLSContext(ctx, network, addr)
264264+ }
265265+ } else if d.NetDialContext != nil {
266266+ netDial = func(network, addr string) (net.Conn, error) {
267267+ return d.NetDialContext(ctx, network, addr)
268268+ }
269269+ } else if d.NetDial != nil {
270270+ netDial = d.NetDial
271271+ }
272272+ default:
273273+ return nil, nil, errMalformedURL
274274+ }
275275+276276+ if netDial == nil {
277277+ netDialer := &net.Dialer{}
278278+ netDial = func(network, addr string) (net.Conn, error) {
279279+ return netDialer.DialContext(ctx, network, addr)
280280+ }
281281+ }
282282+283283+ // If needed, wrap the dial function to set the connection deadline.
284284+ if deadline, ok := ctx.Deadline(); ok {
285285+ forwardDial := netDial
286286+ netDial = func(network, addr string) (net.Conn, error) {
287287+ c, err := forwardDial(network, addr)
288288+ if err != nil {
289289+ return nil, err
290290+ }
291291+ err = c.SetDeadline(deadline)
292292+ if err != nil {
293293+ c.Close()
294294+ return nil, err
295295+ }
296296+ return c, nil
297297+ }
298298+ }
299299+300300+ // If needed, wrap the dial function to connect through a proxy.
301301+ if d.Proxy != nil {
302302+ proxyURL, err := d.Proxy(req)
303303+ if err != nil {
304304+ return nil, nil, err
305305+ }
306306+ if proxyURL != nil {
307307+ dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))
308308+ if err != nil {
309309+ return nil, nil, err
310310+ }
311311+ netDial = dialer.Dial
312312+ }
313313+ }
314314+315315+ hostPort, hostNoPort := hostPortNoPort(u)
316316+ trace := httptrace.ContextClientTrace(ctx)
317317+ if trace != nil && trace.GetConn != nil {
318318+ trace.GetConn(hostPort)
319319+ }
320320+321321+ netConn, err := netDial("tcp", hostPort)
322322+ if err != nil {
323323+ return nil, nil, err
324324+ }
325325+ if trace != nil && trace.GotConn != nil {
326326+ trace.GotConn(httptrace.GotConnInfo{
327327+ Conn: netConn,
328328+ })
329329+ }
330330+331331+ defer func() {
332332+ if netConn != nil {
333333+ netConn.Close()
334334+ }
335335+ }()
336336+337337+ if u.Scheme == "https" && d.NetDialTLSContext == nil {
338338+ // If NetDialTLSContext is set, assume that the TLS handshake has already been done
339339+340340+ cfg := cloneTLSConfig(d.TLSClientConfig)
341341+ if cfg.ServerName == "" {
342342+ cfg.ServerName = hostNoPort
343343+ }
344344+ tlsConn := tls.Client(netConn, cfg)
345345+ netConn = tlsConn
346346+347347+ if trace != nil && trace.TLSHandshakeStart != nil {
348348+ trace.TLSHandshakeStart()
349349+ }
350350+ err := doHandshake(ctx, tlsConn, cfg)
351351+ if trace != nil && trace.TLSHandshakeDone != nil {
352352+ trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
353353+ }
354354+355355+ if err != nil {
356356+ return nil, nil, err
357357+ }
358358+ }
359359+360360+ conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil)
361361+362362+ if err := req.Write(netConn); err != nil {
363363+ return nil, nil, err
364364+ }
365365+366366+ if trace != nil && trace.GotFirstResponseByte != nil {
367367+ if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 {
368368+ trace.GotFirstResponseByte()
369369+ }
370370+ }
371371+372372+ resp, err := http.ReadResponse(conn.br, req)
373373+ if err != nil {
374374+ if d.TLSClientConfig != nil {
375375+ for _, proto := range d.TLSClientConfig.NextProtos {
376376+ if proto != "http/1.1" {
377377+ return nil, nil, fmt.Errorf(
378378+ "websocket: protocol %q was given but is not supported;"+
379379+ "sharing tls.Config with net/http Transport can cause this error: %w",
380380+ proto, err,
381381+ )
382382+ }
383383+ }
384384+ }
385385+ return nil, nil, err
386386+ }
387387+388388+ if d.Jar != nil {
389389+ if rc := resp.Cookies(); len(rc) > 0 {
390390+ d.Jar.SetCookies(u, rc)
391391+ }
392392+ }
393393+394394+ if resp.StatusCode != 101 ||
395395+ !tokenListContainsValue(resp.Header, "Upgrade", "websocket") ||
396396+ !tokenListContainsValue(resp.Header, "Connection", "upgrade") ||
397397+ resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
398398+ // Before closing the network connection on return from this
399399+ // function, slurp up some of the response to aid application
400400+ // debugging.
401401+ buf := make([]byte, 1024)
402402+ n, _ := io.ReadFull(resp.Body, buf)
403403+ resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
404404+ return nil, resp, ErrBadHandshake
405405+ }
406406+407407+ for _, ext := range parseExtensions(resp.Header) {
408408+ if ext[""] != "permessage-deflate" {
409409+ continue
410410+ }
411411+ _, snct := ext["server_no_context_takeover"]
412412+ _, cnct := ext["client_no_context_takeover"]
413413+ if !snct || !cnct {
414414+ return nil, resp, errInvalidCompression
415415+ }
416416+ conn.newCompressionWriter = compressNoContextTakeover
417417+ conn.newDecompressionReader = decompressNoContextTakeover
418418+ break
419419+ }
420420+421421+ resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
422422+ conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
423423+424424+ netConn.SetDeadline(time.Time{})
425425+ netConn = nil // to avoid close in defer.
426426+ return conn, resp, nil
427427+}
428428+429429+func cloneTLSConfig(cfg *tls.Config) *tls.Config {
430430+ if cfg == nil {
431431+ return &tls.Config{}
432432+ }
433433+ return cfg.Clone()
434434+}
···11+// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "compress/flate"
99+ "errors"
1010+ "io"
1111+ "strings"
1212+ "sync"
1313+)
1414+1515+const (
1616+ minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6
1717+ maxCompressionLevel = flate.BestCompression
1818+ defaultCompressionLevel = 1
1919+)
2020+2121+var (
2222+ flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool
2323+ flateReaderPool = sync.Pool{New: func() interface{} {
2424+ return flate.NewReader(nil)
2525+ }}
2626+)
2727+2828+func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
2929+ const tail =
3030+ // Add four bytes as specified in RFC
3131+ "\x00\x00\xff\xff" +
3232+ // Add final block to squelch unexpected EOF error from flate reader.
3333+ "\x01\x00\x00\xff\xff"
3434+3535+ fr, _ := flateReaderPool.Get().(io.ReadCloser)
3636+ fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)
3737+ return &flateReadWrapper{fr}
3838+}
3939+4040+func isValidCompressionLevel(level int) bool {
4141+ return minCompressionLevel <= level && level <= maxCompressionLevel
4242+}
4343+4444+func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {
4545+ p := &flateWriterPools[level-minCompressionLevel]
4646+ tw := &truncWriter{w: w}
4747+ fw, _ := p.Get().(*flate.Writer)
4848+ if fw == nil {
4949+ fw, _ = flate.NewWriter(tw, level)
5050+ } else {
5151+ fw.Reset(tw)
5252+ }
5353+ return &flateWriteWrapper{fw: fw, tw: tw, p: p}
5454+}
5555+5656+// truncWriter is an io.Writer that writes all but the last four bytes of the
5757+// stream to another io.Writer.
5858+type truncWriter struct {
5959+ w io.WriteCloser
6060+ n int
6161+ p [4]byte
6262+}
6363+6464+func (w *truncWriter) Write(p []byte) (int, error) {
6565+ n := 0
6666+6767+ // fill buffer first for simplicity.
6868+ if w.n < len(w.p) {
6969+ n = copy(w.p[w.n:], p)
7070+ p = p[n:]
7171+ w.n += n
7272+ if len(p) == 0 {
7373+ return n, nil
7474+ }
7575+ }
7676+7777+ m := len(p)
7878+ if m > len(w.p) {
7979+ m = len(w.p)
8080+ }
8181+8282+ if nn, err := w.w.Write(w.p[:m]); err != nil {
8383+ return n + nn, err
8484+ }
8585+8686+ copy(w.p[:], w.p[m:])
8787+ copy(w.p[len(w.p)-m:], p[len(p)-m:])
8888+ nn, err := w.w.Write(p[:len(p)-m])
8989+ return n + nn, err
9090+}
9191+9292+type flateWriteWrapper struct {
9393+ fw *flate.Writer
9494+ tw *truncWriter
9595+ p *sync.Pool
9696+}
9797+9898+func (w *flateWriteWrapper) Write(p []byte) (int, error) {
9999+ if w.fw == nil {
100100+ return 0, errWriteClosed
101101+ }
102102+ return w.fw.Write(p)
103103+}
104104+105105+func (w *flateWriteWrapper) Close() error {
106106+ if w.fw == nil {
107107+ return errWriteClosed
108108+ }
109109+ err1 := w.fw.Flush()
110110+ w.p.Put(w.fw)
111111+ w.fw = nil
112112+ if w.tw.p != [4]byte{0, 0, 0xff, 0xff} {
113113+ return errors.New("websocket: internal error, unexpected bytes at end of flate stream")
114114+ }
115115+ err2 := w.tw.w.Close()
116116+ if err1 != nil {
117117+ return err1
118118+ }
119119+ return err2
120120+}
121121+122122+type flateReadWrapper struct {
123123+ fr io.ReadCloser
124124+}
125125+126126+func (r *flateReadWrapper) Read(p []byte) (int, error) {
127127+ if r.fr == nil {
128128+ return 0, io.ErrClosedPipe
129129+ }
130130+ n, err := r.fr.Read(p)
131131+ if err == io.EOF {
132132+ // Preemptively place the reader back in the pool. This helps with
133133+ // scenarios where the application does not call NextReader() soon after
134134+ // this final read.
135135+ r.Close()
136136+ }
137137+ return n, err
138138+}
139139+140140+func (r *flateReadWrapper) Close() error {
141141+ if r.fr == nil {
142142+ return io.ErrClosedPipe
143143+ }
144144+ err := r.fr.Close()
145145+ flateReaderPool.Put(r.fr)
146146+ r.fr = nil
147147+ return err
148148+}
+1238
vendor/github.com/gorilla/websocket/conn.go
···11+// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "bufio"
99+ "encoding/binary"
1010+ "errors"
1111+ "io"
1212+ "io/ioutil"
1313+ "math/rand"
1414+ "net"
1515+ "strconv"
1616+ "strings"
1717+ "sync"
1818+ "time"
1919+ "unicode/utf8"
2020+)
2121+2222+const (
2323+ // Frame header byte 0 bits from Section 5.2 of RFC 6455
2424+ finalBit = 1 << 7
2525+ rsv1Bit = 1 << 6
2626+ rsv2Bit = 1 << 5
2727+ rsv3Bit = 1 << 4
2828+2929+ // Frame header byte 1 bits from Section 5.2 of RFC 6455
3030+ maskBit = 1 << 7
3131+3232+ maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask
3333+ maxControlFramePayloadSize = 125
3434+3535+ writeWait = time.Second
3636+3737+ defaultReadBufferSize = 4096
3838+ defaultWriteBufferSize = 4096
3939+4040+ continuationFrame = 0
4141+ noFrame = -1
4242+)
4343+4444+// Close codes defined in RFC 6455, section 11.7.
4545+const (
4646+ CloseNormalClosure = 1000
4747+ CloseGoingAway = 1001
4848+ CloseProtocolError = 1002
4949+ CloseUnsupportedData = 1003
5050+ CloseNoStatusReceived = 1005
5151+ CloseAbnormalClosure = 1006
5252+ CloseInvalidFramePayloadData = 1007
5353+ ClosePolicyViolation = 1008
5454+ CloseMessageTooBig = 1009
5555+ CloseMandatoryExtension = 1010
5656+ CloseInternalServerErr = 1011
5757+ CloseServiceRestart = 1012
5858+ CloseTryAgainLater = 1013
5959+ CloseTLSHandshake = 1015
6060+)
6161+6262+// The message types are defined in RFC 6455, section 11.8.
6363+const (
6464+ // TextMessage denotes a text data message. The text message payload is
6565+ // interpreted as UTF-8 encoded text data.
6666+ TextMessage = 1
6767+6868+ // BinaryMessage denotes a binary data message.
6969+ BinaryMessage = 2
7070+7171+ // CloseMessage denotes a close control message. The optional message
7272+ // payload contains a numeric code and text. Use the FormatCloseMessage
7373+ // function to format a close message payload.
7474+ CloseMessage = 8
7575+7676+ // PingMessage denotes a ping control message. The optional message payload
7777+ // is UTF-8 encoded text.
7878+ PingMessage = 9
7979+8080+ // PongMessage denotes a pong control message. The optional message payload
8181+ // is UTF-8 encoded text.
8282+ PongMessage = 10
8383+)
8484+8585+// ErrCloseSent is returned when the application writes a message to the
8686+// connection after sending a close message.
8787+var ErrCloseSent = errors.New("websocket: close sent")
8888+8989+// ErrReadLimit is returned when reading a message that is larger than the
9090+// read limit set for the connection.
9191+var ErrReadLimit = errors.New("websocket: read limit exceeded")
9292+9393+// netError satisfies the net Error interface.
9494+type netError struct {
9595+ msg string
9696+ temporary bool
9797+ timeout bool
9898+}
9999+100100+func (e *netError) Error() string { return e.msg }
101101+func (e *netError) Temporary() bool { return e.temporary }
102102+func (e *netError) Timeout() bool { return e.timeout }
103103+104104+// CloseError represents a close message.
105105+type CloseError struct {
106106+ // Code is defined in RFC 6455, section 11.7.
107107+ Code int
108108+109109+ // Text is the optional text payload.
110110+ Text string
111111+}
112112+113113+func (e *CloseError) Error() string {
114114+ s := []byte("websocket: close ")
115115+ s = strconv.AppendInt(s, int64(e.Code), 10)
116116+ switch e.Code {
117117+ case CloseNormalClosure:
118118+ s = append(s, " (normal)"...)
119119+ case CloseGoingAway:
120120+ s = append(s, " (going away)"...)
121121+ case CloseProtocolError:
122122+ s = append(s, " (protocol error)"...)
123123+ case CloseUnsupportedData:
124124+ s = append(s, " (unsupported data)"...)
125125+ case CloseNoStatusReceived:
126126+ s = append(s, " (no status)"...)
127127+ case CloseAbnormalClosure:
128128+ s = append(s, " (abnormal closure)"...)
129129+ case CloseInvalidFramePayloadData:
130130+ s = append(s, " (invalid payload data)"...)
131131+ case ClosePolicyViolation:
132132+ s = append(s, " (policy violation)"...)
133133+ case CloseMessageTooBig:
134134+ s = append(s, " (message too big)"...)
135135+ case CloseMandatoryExtension:
136136+ s = append(s, " (mandatory extension missing)"...)
137137+ case CloseInternalServerErr:
138138+ s = append(s, " (internal server error)"...)
139139+ case CloseTLSHandshake:
140140+ s = append(s, " (TLS handshake error)"...)
141141+ }
142142+ if e.Text != "" {
143143+ s = append(s, ": "...)
144144+ s = append(s, e.Text...)
145145+ }
146146+ return string(s)
147147+}
148148+149149+// IsCloseError returns boolean indicating whether the error is a *CloseError
150150+// with one of the specified codes.
151151+func IsCloseError(err error, codes ...int) bool {
152152+ if e, ok := err.(*CloseError); ok {
153153+ for _, code := range codes {
154154+ if e.Code == code {
155155+ return true
156156+ }
157157+ }
158158+ }
159159+ return false
160160+}
161161+162162+// IsUnexpectedCloseError returns boolean indicating whether the error is a
163163+// *CloseError with a code not in the list of expected codes.
164164+func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
165165+ if e, ok := err.(*CloseError); ok {
166166+ for _, code := range expectedCodes {
167167+ if e.Code == code {
168168+ return false
169169+ }
170170+ }
171171+ return true
172172+ }
173173+ return false
174174+}
175175+176176+var (
177177+ errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
178178+ errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
179179+ errBadWriteOpCode = errors.New("websocket: bad write message type")
180180+ errWriteClosed = errors.New("websocket: write closed")
181181+ errInvalidControlFrame = errors.New("websocket: invalid control frame")
182182+)
183183+184184+func newMaskKey() [4]byte {
185185+ n := rand.Uint32()
186186+ return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
187187+}
188188+189189+func hideTempErr(err error) error {
190190+ if e, ok := err.(net.Error); ok && e.Temporary() {
191191+ err = &netError{msg: e.Error(), timeout: e.Timeout()}
192192+ }
193193+ return err
194194+}
195195+196196+func isControl(frameType int) bool {
197197+ return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
198198+}
199199+200200+func isData(frameType int) bool {
201201+ return frameType == TextMessage || frameType == BinaryMessage
202202+}
203203+204204+var validReceivedCloseCodes = map[int]bool{
205205+ // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
206206+207207+ CloseNormalClosure: true,
208208+ CloseGoingAway: true,
209209+ CloseProtocolError: true,
210210+ CloseUnsupportedData: true,
211211+ CloseNoStatusReceived: false,
212212+ CloseAbnormalClosure: false,
213213+ CloseInvalidFramePayloadData: true,
214214+ ClosePolicyViolation: true,
215215+ CloseMessageTooBig: true,
216216+ CloseMandatoryExtension: true,
217217+ CloseInternalServerErr: true,
218218+ CloseServiceRestart: true,
219219+ CloseTryAgainLater: true,
220220+ CloseTLSHandshake: false,
221221+}
222222+223223+func isValidReceivedCloseCode(code int) bool {
224224+ return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
225225+}
226226+227227+// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this
228228+// interface. The type of the value stored in a pool is not specified.
229229+type BufferPool interface {
230230+ // Get gets a value from the pool or returns nil if the pool is empty.
231231+ Get() interface{}
232232+ // Put adds a value to the pool.
233233+ Put(interface{})
234234+}
235235+236236+// writePoolData is the type added to the write buffer pool. This wrapper is
237237+// used to prevent applications from peeking at and depending on the values
238238+// added to the pool.
239239+type writePoolData struct{ buf []byte }
240240+241241+// The Conn type represents a WebSocket connection.
242242+type Conn struct {
243243+ conn net.Conn
244244+ isServer bool
245245+ subprotocol string
246246+247247+ // Write fields
248248+ mu chan struct{} // used as mutex to protect write to conn
249249+ writeBuf []byte // frame is constructed in this buffer.
250250+ writePool BufferPool
251251+ writeBufSize int
252252+ writeDeadline time.Time
253253+ writer io.WriteCloser // the current writer returned to the application
254254+ isWriting bool // for best-effort concurrent write detection
255255+256256+ writeErrMu sync.Mutex
257257+ writeErr error
258258+259259+ enableWriteCompression bool
260260+ compressionLevel int
261261+ newCompressionWriter func(io.WriteCloser, int) io.WriteCloser
262262+263263+ // Read fields
264264+ reader io.ReadCloser // the current reader returned to the application
265265+ readErr error
266266+ br *bufio.Reader
267267+ // bytes remaining in current frame.
268268+ // set setReadRemaining to safely update this value and prevent overflow
269269+ readRemaining int64
270270+ readFinal bool // true the current message has more frames.
271271+ readLength int64 // Message size.
272272+ readLimit int64 // Maximum message size.
273273+ readMaskPos int
274274+ readMaskKey [4]byte
275275+ handlePong func(string) error
276276+ handlePing func(string) error
277277+ handleClose func(int, string) error
278278+ readErrCount int
279279+ messageReader *messageReader // the current low-level reader
280280+281281+ readDecompress bool // whether last read frame had RSV1 set
282282+ newDecompressionReader func(io.Reader) io.ReadCloser
283283+}
284284+285285+func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn {
286286+287287+ if br == nil {
288288+ if readBufferSize == 0 {
289289+ readBufferSize = defaultReadBufferSize
290290+ } else if readBufferSize < maxControlFramePayloadSize {
291291+ // must be large enough for control frame
292292+ readBufferSize = maxControlFramePayloadSize
293293+ }
294294+ br = bufio.NewReaderSize(conn, readBufferSize)
295295+ }
296296+297297+ if writeBufferSize <= 0 {
298298+ writeBufferSize = defaultWriteBufferSize
299299+ }
300300+ writeBufferSize += maxFrameHeaderSize
301301+302302+ if writeBuf == nil && writeBufferPool == nil {
303303+ writeBuf = make([]byte, writeBufferSize)
304304+ }
305305+306306+ mu := make(chan struct{}, 1)
307307+ mu <- struct{}{}
308308+ c := &Conn{
309309+ isServer: isServer,
310310+ br: br,
311311+ conn: conn,
312312+ mu: mu,
313313+ readFinal: true,
314314+ writeBuf: writeBuf,
315315+ writePool: writeBufferPool,
316316+ writeBufSize: writeBufferSize,
317317+ enableWriteCompression: true,
318318+ compressionLevel: defaultCompressionLevel,
319319+ }
320320+ c.SetCloseHandler(nil)
321321+ c.SetPingHandler(nil)
322322+ c.SetPongHandler(nil)
323323+ return c
324324+}
325325+326326+// setReadRemaining tracks the number of bytes remaining on the connection. If n
327327+// overflows, an ErrReadLimit is returned.
328328+func (c *Conn) setReadRemaining(n int64) error {
329329+ if n < 0 {
330330+ return ErrReadLimit
331331+ }
332332+333333+ c.readRemaining = n
334334+ return nil
335335+}
336336+337337+// Subprotocol returns the negotiated protocol for the connection.
338338+func (c *Conn) Subprotocol() string {
339339+ return c.subprotocol
340340+}
341341+342342+// Close closes the underlying network connection without sending or waiting
343343+// for a close message.
344344+func (c *Conn) Close() error {
345345+ return c.conn.Close()
346346+}
347347+348348+// LocalAddr returns the local network address.
349349+func (c *Conn) LocalAddr() net.Addr {
350350+ return c.conn.LocalAddr()
351351+}
352352+353353+// RemoteAddr returns the remote network address.
354354+func (c *Conn) RemoteAddr() net.Addr {
355355+ return c.conn.RemoteAddr()
356356+}
357357+358358+// Write methods
359359+360360+func (c *Conn) writeFatal(err error) error {
361361+ err = hideTempErr(err)
362362+ c.writeErrMu.Lock()
363363+ if c.writeErr == nil {
364364+ c.writeErr = err
365365+ }
366366+ c.writeErrMu.Unlock()
367367+ return err
368368+}
369369+370370+func (c *Conn) read(n int) ([]byte, error) {
371371+ p, err := c.br.Peek(n)
372372+ if err == io.EOF {
373373+ err = errUnexpectedEOF
374374+ }
375375+ c.br.Discard(len(p))
376376+ return p, err
377377+}
378378+379379+func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {
380380+ <-c.mu
381381+ defer func() { c.mu <- struct{}{} }()
382382+383383+ c.writeErrMu.Lock()
384384+ err := c.writeErr
385385+ c.writeErrMu.Unlock()
386386+ if err != nil {
387387+ return err
388388+ }
389389+390390+ c.conn.SetWriteDeadline(deadline)
391391+ if len(buf1) == 0 {
392392+ _, err = c.conn.Write(buf0)
393393+ } else {
394394+ err = c.writeBufs(buf0, buf1)
395395+ }
396396+ if err != nil {
397397+ return c.writeFatal(err)
398398+ }
399399+ if frameType == CloseMessage {
400400+ c.writeFatal(ErrCloseSent)
401401+ }
402402+ return nil
403403+}
404404+405405+func (c *Conn) writeBufs(bufs ...[]byte) error {
406406+ b := net.Buffers(bufs)
407407+ _, err := b.WriteTo(c.conn)
408408+ return err
409409+}
410410+411411+// WriteControl writes a control message with the given deadline. The allowed
412412+// message types are CloseMessage, PingMessage and PongMessage.
413413+func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
414414+ if !isControl(messageType) {
415415+ return errBadWriteOpCode
416416+ }
417417+ if len(data) > maxControlFramePayloadSize {
418418+ return errInvalidControlFrame
419419+ }
420420+421421+ b0 := byte(messageType) | finalBit
422422+ b1 := byte(len(data))
423423+ if !c.isServer {
424424+ b1 |= maskBit
425425+ }
426426+427427+ buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
428428+ buf = append(buf, b0, b1)
429429+430430+ if c.isServer {
431431+ buf = append(buf, data...)
432432+ } else {
433433+ key := newMaskKey()
434434+ buf = append(buf, key[:]...)
435435+ buf = append(buf, data...)
436436+ maskBytes(key, 0, buf[6:])
437437+ }
438438+439439+ d := 1000 * time.Hour
440440+ if !deadline.IsZero() {
441441+ d = deadline.Sub(time.Now())
442442+ if d < 0 {
443443+ return errWriteTimeout
444444+ }
445445+ }
446446+447447+ timer := time.NewTimer(d)
448448+ select {
449449+ case <-c.mu:
450450+ timer.Stop()
451451+ case <-timer.C:
452452+ return errWriteTimeout
453453+ }
454454+ defer func() { c.mu <- struct{}{} }()
455455+456456+ c.writeErrMu.Lock()
457457+ err := c.writeErr
458458+ c.writeErrMu.Unlock()
459459+ if err != nil {
460460+ return err
461461+ }
462462+463463+ c.conn.SetWriteDeadline(deadline)
464464+ _, err = c.conn.Write(buf)
465465+ if err != nil {
466466+ return c.writeFatal(err)
467467+ }
468468+ if messageType == CloseMessage {
469469+ c.writeFatal(ErrCloseSent)
470470+ }
471471+ return err
472472+}
473473+474474+// beginMessage prepares a connection and message writer for a new message.
475475+func (c *Conn) beginMessage(mw *messageWriter, messageType int) error {
476476+ // Close previous writer if not already closed by the application. It's
477477+ // probably better to return an error in this situation, but we cannot
478478+ // change this without breaking existing applications.
479479+ if c.writer != nil {
480480+ c.writer.Close()
481481+ c.writer = nil
482482+ }
483483+484484+ if !isControl(messageType) && !isData(messageType) {
485485+ return errBadWriteOpCode
486486+ }
487487+488488+ c.writeErrMu.Lock()
489489+ err := c.writeErr
490490+ c.writeErrMu.Unlock()
491491+ if err != nil {
492492+ return err
493493+ }
494494+495495+ mw.c = c
496496+ mw.frameType = messageType
497497+ mw.pos = maxFrameHeaderSize
498498+499499+ if c.writeBuf == nil {
500500+ wpd, ok := c.writePool.Get().(writePoolData)
501501+ if ok {
502502+ c.writeBuf = wpd.buf
503503+ } else {
504504+ c.writeBuf = make([]byte, c.writeBufSize)
505505+ }
506506+ }
507507+ return nil
508508+}
509509+510510+// NextWriter returns a writer for the next message to send. The writer's Close
511511+// method flushes the complete message to the network.
512512+//
513513+// There can be at most one open writer on a connection. NextWriter closes the
514514+// previous writer if the application has not already done so.
515515+//
516516+// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and
517517+// PongMessage) are supported.
518518+func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
519519+ var mw messageWriter
520520+ if err := c.beginMessage(&mw, messageType); err != nil {
521521+ return nil, err
522522+ }
523523+ c.writer = &mw
524524+ if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {
525525+ w := c.newCompressionWriter(c.writer, c.compressionLevel)
526526+ mw.compress = true
527527+ c.writer = w
528528+ }
529529+ return c.writer, nil
530530+}
531531+532532+type messageWriter struct {
533533+ c *Conn
534534+ compress bool // whether next call to flushFrame should set RSV1
535535+ pos int // end of data in writeBuf.
536536+ frameType int // type of the current frame.
537537+ err error
538538+}
539539+540540+func (w *messageWriter) endMessage(err error) error {
541541+ if w.err != nil {
542542+ return err
543543+ }
544544+ c := w.c
545545+ w.err = err
546546+ c.writer = nil
547547+ if c.writePool != nil {
548548+ c.writePool.Put(writePoolData{buf: c.writeBuf})
549549+ c.writeBuf = nil
550550+ }
551551+ return err
552552+}
553553+554554+// flushFrame writes buffered data and extra as a frame to the network. The
555555+// final argument indicates that this is the last frame in the message.
556556+func (w *messageWriter) flushFrame(final bool, extra []byte) error {
557557+ c := w.c
558558+ length := w.pos - maxFrameHeaderSize + len(extra)
559559+560560+ // Check for invalid control frames.
561561+ if isControl(w.frameType) &&
562562+ (!final || length > maxControlFramePayloadSize) {
563563+ return w.endMessage(errInvalidControlFrame)
564564+ }
565565+566566+ b0 := byte(w.frameType)
567567+ if final {
568568+ b0 |= finalBit
569569+ }
570570+ if w.compress {
571571+ b0 |= rsv1Bit
572572+ }
573573+ w.compress = false
574574+575575+ b1 := byte(0)
576576+ if !c.isServer {
577577+ b1 |= maskBit
578578+ }
579579+580580+ // Assume that the frame starts at beginning of c.writeBuf.
581581+ framePos := 0
582582+ if c.isServer {
583583+ // Adjust up if mask not included in the header.
584584+ framePos = 4
585585+ }
586586+587587+ switch {
588588+ case length >= 65536:
589589+ c.writeBuf[framePos] = b0
590590+ c.writeBuf[framePos+1] = b1 | 127
591591+ binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
592592+ case length > 125:
593593+ framePos += 6
594594+ c.writeBuf[framePos] = b0
595595+ c.writeBuf[framePos+1] = b1 | 126
596596+ binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
597597+ default:
598598+ framePos += 8
599599+ c.writeBuf[framePos] = b0
600600+ c.writeBuf[framePos+1] = b1 | byte(length)
601601+ }
602602+603603+ if !c.isServer {
604604+ key := newMaskKey()
605605+ copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
606606+ maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])
607607+ if len(extra) > 0 {
608608+ return w.endMessage(c.writeFatal(errors.New("websocket: internal error, extra used in client mode")))
609609+ }
610610+ }
611611+612612+ // Write the buffers to the connection with best-effort detection of
613613+ // concurrent writes. See the concurrency section in the package
614614+ // documentation for more info.
615615+616616+ if c.isWriting {
617617+ panic("concurrent write to websocket connection")
618618+ }
619619+ c.isWriting = true
620620+621621+ err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)
622622+623623+ if !c.isWriting {
624624+ panic("concurrent write to websocket connection")
625625+ }
626626+ c.isWriting = false
627627+628628+ if err != nil {
629629+ return w.endMessage(err)
630630+ }
631631+632632+ if final {
633633+ w.endMessage(errWriteClosed)
634634+ return nil
635635+ }
636636+637637+ // Setup for next frame.
638638+ w.pos = maxFrameHeaderSize
639639+ w.frameType = continuationFrame
640640+ return nil
641641+}
642642+643643+func (w *messageWriter) ncopy(max int) (int, error) {
644644+ n := len(w.c.writeBuf) - w.pos
645645+ if n <= 0 {
646646+ if err := w.flushFrame(false, nil); err != nil {
647647+ return 0, err
648648+ }
649649+ n = len(w.c.writeBuf) - w.pos
650650+ }
651651+ if n > max {
652652+ n = max
653653+ }
654654+ return n, nil
655655+}
656656+657657+func (w *messageWriter) Write(p []byte) (int, error) {
658658+ if w.err != nil {
659659+ return 0, w.err
660660+ }
661661+662662+ if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
663663+ // Don't buffer large messages.
664664+ err := w.flushFrame(false, p)
665665+ if err != nil {
666666+ return 0, err
667667+ }
668668+ return len(p), nil
669669+ }
670670+671671+ nn := len(p)
672672+ for len(p) > 0 {
673673+ n, err := w.ncopy(len(p))
674674+ if err != nil {
675675+ return 0, err
676676+ }
677677+ copy(w.c.writeBuf[w.pos:], p[:n])
678678+ w.pos += n
679679+ p = p[n:]
680680+ }
681681+ return nn, nil
682682+}
683683+684684+func (w *messageWriter) WriteString(p string) (int, error) {
685685+ if w.err != nil {
686686+ return 0, w.err
687687+ }
688688+689689+ nn := len(p)
690690+ for len(p) > 0 {
691691+ n, err := w.ncopy(len(p))
692692+ if err != nil {
693693+ return 0, err
694694+ }
695695+ copy(w.c.writeBuf[w.pos:], p[:n])
696696+ w.pos += n
697697+ p = p[n:]
698698+ }
699699+ return nn, nil
700700+}
701701+702702+func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
703703+ if w.err != nil {
704704+ return 0, w.err
705705+ }
706706+ for {
707707+ if w.pos == len(w.c.writeBuf) {
708708+ err = w.flushFrame(false, nil)
709709+ if err != nil {
710710+ break
711711+ }
712712+ }
713713+ var n int
714714+ n, err = r.Read(w.c.writeBuf[w.pos:])
715715+ w.pos += n
716716+ nn += int64(n)
717717+ if err != nil {
718718+ if err == io.EOF {
719719+ err = nil
720720+ }
721721+ break
722722+ }
723723+ }
724724+ return nn, err
725725+}
726726+727727+func (w *messageWriter) Close() error {
728728+ if w.err != nil {
729729+ return w.err
730730+ }
731731+ return w.flushFrame(true, nil)
732732+}
733733+734734+// WritePreparedMessage writes prepared message into connection.
735735+func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {
736736+ frameType, frameData, err := pm.frame(prepareKey{
737737+ isServer: c.isServer,
738738+ compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),
739739+ compressionLevel: c.compressionLevel,
740740+ })
741741+ if err != nil {
742742+ return err
743743+ }
744744+ if c.isWriting {
745745+ panic("concurrent write to websocket connection")
746746+ }
747747+ c.isWriting = true
748748+ err = c.write(frameType, c.writeDeadline, frameData, nil)
749749+ if !c.isWriting {
750750+ panic("concurrent write to websocket connection")
751751+ }
752752+ c.isWriting = false
753753+ return err
754754+}
755755+756756+// WriteMessage is a helper method for getting a writer using NextWriter,
757757+// writing the message and closing the writer.
758758+func (c *Conn) WriteMessage(messageType int, data []byte) error {
759759+760760+ if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {
761761+ // Fast path with no allocations and single frame.
762762+763763+ var mw messageWriter
764764+ if err := c.beginMessage(&mw, messageType); err != nil {
765765+ return err
766766+ }
767767+ n := copy(c.writeBuf[mw.pos:], data)
768768+ mw.pos += n
769769+ data = data[n:]
770770+ return mw.flushFrame(true, data)
771771+ }
772772+773773+ w, err := c.NextWriter(messageType)
774774+ if err != nil {
775775+ return err
776776+ }
777777+ if _, err = w.Write(data); err != nil {
778778+ return err
779779+ }
780780+ return w.Close()
781781+}
782782+783783+// SetWriteDeadline sets the write deadline on the underlying network
784784+// connection. After a write has timed out, the websocket state is corrupt and
785785+// all future writes will return an error. A zero value for t means writes will
786786+// not time out.
787787+func (c *Conn) SetWriteDeadline(t time.Time) error {
788788+ c.writeDeadline = t
789789+ return nil
790790+}
791791+792792+// Read methods
793793+794794+func (c *Conn) advanceFrame() (int, error) {
795795+ // 1. Skip remainder of previous frame.
796796+797797+ if c.readRemaining > 0 {
798798+ if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
799799+ return noFrame, err
800800+ }
801801+ }
802802+803803+ // 2. Read and parse first two bytes of frame header.
804804+ // To aid debugging, collect and report all errors in the first two bytes
805805+ // of the header.
806806+807807+ var errors []string
808808+809809+ p, err := c.read(2)
810810+ if err != nil {
811811+ return noFrame, err
812812+ }
813813+814814+ frameType := int(p[0] & 0xf)
815815+ final := p[0]&finalBit != 0
816816+ rsv1 := p[0]&rsv1Bit != 0
817817+ rsv2 := p[0]&rsv2Bit != 0
818818+ rsv3 := p[0]&rsv3Bit != 0
819819+ mask := p[1]&maskBit != 0
820820+ c.setReadRemaining(int64(p[1] & 0x7f))
821821+822822+ c.readDecompress = false
823823+ if rsv1 {
824824+ if c.newDecompressionReader != nil {
825825+ c.readDecompress = true
826826+ } else {
827827+ errors = append(errors, "RSV1 set")
828828+ }
829829+ }
830830+831831+ if rsv2 {
832832+ errors = append(errors, "RSV2 set")
833833+ }
834834+835835+ if rsv3 {
836836+ errors = append(errors, "RSV3 set")
837837+ }
838838+839839+ switch frameType {
840840+ case CloseMessage, PingMessage, PongMessage:
841841+ if c.readRemaining > maxControlFramePayloadSize {
842842+ errors = append(errors, "len > 125 for control")
843843+ }
844844+ if !final {
845845+ errors = append(errors, "FIN not set on control")
846846+ }
847847+ case TextMessage, BinaryMessage:
848848+ if !c.readFinal {
849849+ errors = append(errors, "data before FIN")
850850+ }
851851+ c.readFinal = final
852852+ case continuationFrame:
853853+ if c.readFinal {
854854+ errors = append(errors, "continuation after FIN")
855855+ }
856856+ c.readFinal = final
857857+ default:
858858+ errors = append(errors, "bad opcode "+strconv.Itoa(frameType))
859859+ }
860860+861861+ if mask != c.isServer {
862862+ errors = append(errors, "bad MASK")
863863+ }
864864+865865+ if len(errors) > 0 {
866866+ return noFrame, c.handleProtocolError(strings.Join(errors, ", "))
867867+ }
868868+869869+ // 3. Read and parse frame length as per
870870+ // https://tools.ietf.org/html/rfc6455#section-5.2
871871+ //
872872+ // The length of the "Payload data", in bytes: if 0-125, that is the payload
873873+ // length.
874874+ // - If 126, the following 2 bytes interpreted as a 16-bit unsigned
875875+ // integer are the payload length.
876876+ // - If 127, the following 8 bytes interpreted as
877877+ // a 64-bit unsigned integer (the most significant bit MUST be 0) are the
878878+ // payload length. Multibyte length quantities are expressed in network byte
879879+ // order.
880880+881881+ switch c.readRemaining {
882882+ case 126:
883883+ p, err := c.read(2)
884884+ if err != nil {
885885+ return noFrame, err
886886+ }
887887+888888+ if err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil {
889889+ return noFrame, err
890890+ }
891891+ case 127:
892892+ p, err := c.read(8)
893893+ if err != nil {
894894+ return noFrame, err
895895+ }
896896+897897+ if err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil {
898898+ return noFrame, err
899899+ }
900900+ }
901901+902902+ // 4. Handle frame masking.
903903+904904+ if mask {
905905+ c.readMaskPos = 0
906906+ p, err := c.read(len(c.readMaskKey))
907907+ if err != nil {
908908+ return noFrame, err
909909+ }
910910+ copy(c.readMaskKey[:], p)
911911+ }
912912+913913+ // 5. For text and binary messages, enforce read limit and return.
914914+915915+ if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
916916+917917+ c.readLength += c.readRemaining
918918+ // Don't allow readLength to overflow in the presence of a large readRemaining
919919+ // counter.
920920+ if c.readLength < 0 {
921921+ return noFrame, ErrReadLimit
922922+ }
923923+924924+ if c.readLimit > 0 && c.readLength > c.readLimit {
925925+ c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
926926+ return noFrame, ErrReadLimit
927927+ }
928928+929929+ return frameType, nil
930930+ }
931931+932932+ // 6. Read control frame payload.
933933+934934+ var payload []byte
935935+ if c.readRemaining > 0 {
936936+ payload, err = c.read(int(c.readRemaining))
937937+ c.setReadRemaining(0)
938938+ if err != nil {
939939+ return noFrame, err
940940+ }
941941+ if c.isServer {
942942+ maskBytes(c.readMaskKey, 0, payload)
943943+ }
944944+ }
945945+946946+ // 7. Process control frame payload.
947947+948948+ switch frameType {
949949+ case PongMessage:
950950+ if err := c.handlePong(string(payload)); err != nil {
951951+ return noFrame, err
952952+ }
953953+ case PingMessage:
954954+ if err := c.handlePing(string(payload)); err != nil {
955955+ return noFrame, err
956956+ }
957957+ case CloseMessage:
958958+ closeCode := CloseNoStatusReceived
959959+ closeText := ""
960960+ if len(payload) >= 2 {
961961+ closeCode = int(binary.BigEndian.Uint16(payload))
962962+ if !isValidReceivedCloseCode(closeCode) {
963963+ return noFrame, c.handleProtocolError("bad close code " + strconv.Itoa(closeCode))
964964+ }
965965+ closeText = string(payload[2:])
966966+ if !utf8.ValidString(closeText) {
967967+ return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
968968+ }
969969+ }
970970+ if err := c.handleClose(closeCode, closeText); err != nil {
971971+ return noFrame, err
972972+ }
973973+ return noFrame, &CloseError{Code: closeCode, Text: closeText}
974974+ }
975975+976976+ return frameType, nil
977977+}
978978+979979+func (c *Conn) handleProtocolError(message string) error {
980980+ data := FormatCloseMessage(CloseProtocolError, message)
981981+ if len(data) > maxControlFramePayloadSize {
982982+ data = data[:maxControlFramePayloadSize]
983983+ }
984984+ c.WriteControl(CloseMessage, data, time.Now().Add(writeWait))
985985+ return errors.New("websocket: " + message)
986986+}
987987+988988+// NextReader returns the next data message received from the peer. The
989989+// returned messageType is either TextMessage or BinaryMessage.
990990+//
991991+// There can be at most one open reader on a connection. NextReader discards
992992+// the previous message if the application has not already consumed it.
993993+//
994994+// Applications must break out of the application's read loop when this method
995995+// returns a non-nil error value. Errors returned from this method are
996996+// permanent. Once this method returns a non-nil error, all subsequent calls to
997997+// this method return the same error.
998998+func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
999999+ // Close previous reader, only relevant for decompression.
10001000+ if c.reader != nil {
10011001+ c.reader.Close()
10021002+ c.reader = nil
10031003+ }
10041004+10051005+ c.messageReader = nil
10061006+ c.readLength = 0
10071007+10081008+ for c.readErr == nil {
10091009+ frameType, err := c.advanceFrame()
10101010+ if err != nil {
10111011+ c.readErr = hideTempErr(err)
10121012+ break
10131013+ }
10141014+10151015+ if frameType == TextMessage || frameType == BinaryMessage {
10161016+ c.messageReader = &messageReader{c}
10171017+ c.reader = c.messageReader
10181018+ if c.readDecompress {
10191019+ c.reader = c.newDecompressionReader(c.reader)
10201020+ }
10211021+ return frameType, c.reader, nil
10221022+ }
10231023+ }
10241024+10251025+ // Applications that do handle the error returned from this method spin in
10261026+ // tight loop on connection failure. To help application developers detect
10271027+ // this error, panic on repeated reads to the failed connection.
10281028+ c.readErrCount++
10291029+ if c.readErrCount >= 1000 {
10301030+ panic("repeated read on failed websocket connection")
10311031+ }
10321032+10331033+ return noFrame, nil, c.readErr
10341034+}
10351035+10361036+type messageReader struct{ c *Conn }
10371037+10381038+func (r *messageReader) Read(b []byte) (int, error) {
10391039+ c := r.c
10401040+ if c.messageReader != r {
10411041+ return 0, io.EOF
10421042+ }
10431043+10441044+ for c.readErr == nil {
10451045+10461046+ if c.readRemaining > 0 {
10471047+ if int64(len(b)) > c.readRemaining {
10481048+ b = b[:c.readRemaining]
10491049+ }
10501050+ n, err := c.br.Read(b)
10511051+ c.readErr = hideTempErr(err)
10521052+ if c.isServer {
10531053+ c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
10541054+ }
10551055+ rem := c.readRemaining
10561056+ rem -= int64(n)
10571057+ c.setReadRemaining(rem)
10581058+ if c.readRemaining > 0 && c.readErr == io.EOF {
10591059+ c.readErr = errUnexpectedEOF
10601060+ }
10611061+ return n, c.readErr
10621062+ }
10631063+10641064+ if c.readFinal {
10651065+ c.messageReader = nil
10661066+ return 0, io.EOF
10671067+ }
10681068+10691069+ frameType, err := c.advanceFrame()
10701070+ switch {
10711071+ case err != nil:
10721072+ c.readErr = hideTempErr(err)
10731073+ case frameType == TextMessage || frameType == BinaryMessage:
10741074+ c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
10751075+ }
10761076+ }
10771077+10781078+ err := c.readErr
10791079+ if err == io.EOF && c.messageReader == r {
10801080+ err = errUnexpectedEOF
10811081+ }
10821082+ return 0, err
10831083+}
10841084+10851085+func (r *messageReader) Close() error {
10861086+ return nil
10871087+}
10881088+10891089+// ReadMessage is a helper method for getting a reader using NextReader and
10901090+// reading from that reader to a buffer.
10911091+func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
10921092+ var r io.Reader
10931093+ messageType, r, err = c.NextReader()
10941094+ if err != nil {
10951095+ return messageType, nil, err
10961096+ }
10971097+ p, err = ioutil.ReadAll(r)
10981098+ return messageType, p, err
10991099+}
11001100+11011101+// SetReadDeadline sets the read deadline on the underlying network connection.
11021102+// After a read has timed out, the websocket connection state is corrupt and
11031103+// all future reads will return an error. A zero value for t means reads will
11041104+// not time out.
11051105+func (c *Conn) SetReadDeadline(t time.Time) error {
11061106+ return c.conn.SetReadDeadline(t)
11071107+}
11081108+11091109+// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a
11101110+// message exceeds the limit, the connection sends a close message to the peer
11111111+// and returns ErrReadLimit to the application.
11121112+func (c *Conn) SetReadLimit(limit int64) {
11131113+ c.readLimit = limit
11141114+}
11151115+11161116+// CloseHandler returns the current close handler
11171117+func (c *Conn) CloseHandler() func(code int, text string) error {
11181118+ return c.handleClose
11191119+}
11201120+11211121+// SetCloseHandler sets the handler for close messages received from the peer.
11221122+// The code argument to h is the received close code or CloseNoStatusReceived
11231123+// if the close message is empty. The default close handler sends a close
11241124+// message back to the peer.
11251125+//
11261126+// The handler function is called from the NextReader, ReadMessage and message
11271127+// reader Read methods. The application must read the connection to process
11281128+// close messages as described in the section on Control Messages above.
11291129+//
11301130+// The connection read methods return a CloseError when a close message is
11311131+// received. Most applications should handle close messages as part of their
11321132+// normal error handling. Applications should only set a close handler when the
11331133+// application must perform some action before sending a close message back to
11341134+// the peer.
11351135+func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
11361136+ if h == nil {
11371137+ h = func(code int, text string) error {
11381138+ message := FormatCloseMessage(code, "")
11391139+ c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
11401140+ return nil
11411141+ }
11421142+ }
11431143+ c.handleClose = h
11441144+}
11451145+11461146+// PingHandler returns the current ping handler
11471147+func (c *Conn) PingHandler() func(appData string) error {
11481148+ return c.handlePing
11491149+}
11501150+11511151+// SetPingHandler sets the handler for ping messages received from the peer.
11521152+// The appData argument to h is the PING message application data. The default
11531153+// ping handler sends a pong to the peer.
11541154+//
11551155+// The handler function is called from the NextReader, ReadMessage and message
11561156+// reader Read methods. The application must read the connection to process
11571157+// ping messages as described in the section on Control Messages above.
11581158+func (c *Conn) SetPingHandler(h func(appData string) error) {
11591159+ if h == nil {
11601160+ h = func(message string) error {
11611161+ err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
11621162+ if err == ErrCloseSent {
11631163+ return nil
11641164+ } else if e, ok := err.(net.Error); ok && e.Temporary() {
11651165+ return nil
11661166+ }
11671167+ return err
11681168+ }
11691169+ }
11701170+ c.handlePing = h
11711171+}
11721172+11731173+// PongHandler returns the current pong handler
11741174+func (c *Conn) PongHandler() func(appData string) error {
11751175+ return c.handlePong
11761176+}
11771177+11781178+// SetPongHandler sets the handler for pong messages received from the peer.
11791179+// The appData argument to h is the PONG message application data. The default
11801180+// pong handler does nothing.
11811181+//
11821182+// The handler function is called from the NextReader, ReadMessage and message
11831183+// reader Read methods. The application must read the connection to process
11841184+// pong messages as described in the section on Control Messages above.
11851185+func (c *Conn) SetPongHandler(h func(appData string) error) {
11861186+ if h == nil {
11871187+ h = func(string) error { return nil }
11881188+ }
11891189+ c.handlePong = h
11901190+}
11911191+11921192+// NetConn returns the underlying connection that is wrapped by c.
11931193+// Note that writing to or reading from this connection directly will corrupt the
11941194+// WebSocket connection.
11951195+func (c *Conn) NetConn() net.Conn {
11961196+ return c.conn
11971197+}
11981198+11991199+// UnderlyingConn returns the internal net.Conn. This can be used to further
12001200+// modifications to connection specific flags.
12011201+// Deprecated: Use the NetConn method.
12021202+func (c *Conn) UnderlyingConn() net.Conn {
12031203+ return c.conn
12041204+}
12051205+12061206+// EnableWriteCompression enables and disables write compression of
12071207+// subsequent text and binary messages. This function is a noop if
12081208+// compression was not negotiated with the peer.
12091209+func (c *Conn) EnableWriteCompression(enable bool) {
12101210+ c.enableWriteCompression = enable
12111211+}
12121212+12131213+// SetCompressionLevel sets the flate compression level for subsequent text and
12141214+// binary messages. This function is a noop if compression was not negotiated
12151215+// with the peer. See the compress/flate package for a description of
12161216+// compression levels.
12171217+func (c *Conn) SetCompressionLevel(level int) error {
12181218+ if !isValidCompressionLevel(level) {
12191219+ return errors.New("websocket: invalid compression level")
12201220+ }
12211221+ c.compressionLevel = level
12221222+ return nil
12231223+}
12241224+12251225+// FormatCloseMessage formats closeCode and text as a WebSocket close message.
12261226+// An empty message is returned for code CloseNoStatusReceived.
12271227+func FormatCloseMessage(closeCode int, text string) []byte {
12281228+ if closeCode == CloseNoStatusReceived {
12291229+ // Return empty message because it's illegal to send
12301230+ // CloseNoStatusReceived. Return non-nil value in case application
12311231+ // checks for nil.
12321232+ return []byte{}
12331233+ }
12341234+ buf := make([]byte, 2+len(text))
12351235+ binary.BigEndian.PutUint16(buf, uint16(closeCode))
12361236+ copy(buf[2:], text)
12371237+ return buf
12381238+}
+227
vendor/github.com/gorilla/websocket/doc.go
···11+// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+// Package websocket implements the WebSocket protocol defined in RFC 6455.
66+//
77+// Overview
88+//
99+// The Conn type represents a WebSocket connection. A server application calls
1010+// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn:
1111+//
1212+// var upgrader = websocket.Upgrader{
1313+// ReadBufferSize: 1024,
1414+// WriteBufferSize: 1024,
1515+// }
1616+//
1717+// func handler(w http.ResponseWriter, r *http.Request) {
1818+// conn, err := upgrader.Upgrade(w, r, nil)
1919+// if err != nil {
2020+// log.Println(err)
2121+// return
2222+// }
2323+// ... Use conn to send and receive messages.
2424+// }
2525+//
2626+// Call the connection's WriteMessage and ReadMessage methods to send and
2727+// receive messages as a slice of bytes. This snippet of code shows how to echo
2828+// messages using these methods:
2929+//
3030+// for {
3131+// messageType, p, err := conn.ReadMessage()
3232+// if err != nil {
3333+// log.Println(err)
3434+// return
3535+// }
3636+// if err := conn.WriteMessage(messageType, p); err != nil {
3737+// log.Println(err)
3838+// return
3939+// }
4040+// }
4141+//
4242+// In above snippet of code, p is a []byte and messageType is an int with value
4343+// websocket.BinaryMessage or websocket.TextMessage.
4444+//
4545+// An application can also send and receive messages using the io.WriteCloser
4646+// and io.Reader interfaces. To send a message, call the connection NextWriter
4747+// method to get an io.WriteCloser, write the message to the writer and close
4848+// the writer when done. To receive a message, call the connection NextReader
4949+// method to get an io.Reader and read until io.EOF is returned. This snippet
5050+// shows how to echo messages using the NextWriter and NextReader methods:
5151+//
5252+// for {
5353+// messageType, r, err := conn.NextReader()
5454+// if err != nil {
5555+// return
5656+// }
5757+// w, err := conn.NextWriter(messageType)
5858+// if err != nil {
5959+// return err
6060+// }
6161+// if _, err := io.Copy(w, r); err != nil {
6262+// return err
6363+// }
6464+// if err := w.Close(); err != nil {
6565+// return err
6666+// }
6767+// }
6868+//
6969+// Data Messages
7070+//
7171+// The WebSocket protocol distinguishes between text and binary data messages.
7272+// Text messages are interpreted as UTF-8 encoded text. The interpretation of
7373+// binary messages is left to the application.
7474+//
7575+// This package uses the TextMessage and BinaryMessage integer constants to
7676+// identify the two data message types. The ReadMessage and NextReader methods
7777+// return the type of the received message. The messageType argument to the
7878+// WriteMessage and NextWriter methods specifies the type of a sent message.
7979+//
8080+// It is the application's responsibility to ensure that text messages are
8181+// valid UTF-8 encoded text.
8282+//
8383+// Control Messages
8484+//
8585+// The WebSocket protocol defines three types of control messages: close, ping
8686+// and pong. Call the connection WriteControl, WriteMessage or NextWriter
8787+// methods to send a control message to the peer.
8888+//
8989+// Connections handle received close messages by calling the handler function
9090+// set with the SetCloseHandler method and by returning a *CloseError from the
9191+// NextReader, ReadMessage or the message Read method. The default close
9292+// handler sends a close message to the peer.
9393+//
9494+// Connections handle received ping messages by calling the handler function
9595+// set with the SetPingHandler method. The default ping handler sends a pong
9696+// message to the peer.
9797+//
9898+// Connections handle received pong messages by calling the handler function
9999+// set with the SetPongHandler method. The default pong handler does nothing.
100100+// If an application sends ping messages, then the application should set a
101101+// pong handler to receive the corresponding pong.
102102+//
103103+// The control message handler functions are called from the NextReader,
104104+// ReadMessage and message reader Read methods. The default close and ping
105105+// handlers can block these methods for a short time when the handler writes to
106106+// the connection.
107107+//
108108+// The application must read the connection to process close, ping and pong
109109+// messages sent from the peer. If the application is not otherwise interested
110110+// in messages from the peer, then the application should start a goroutine to
111111+// read and discard messages from the peer. A simple example is:
112112+//
113113+// func readLoop(c *websocket.Conn) {
114114+// for {
115115+// if _, _, err := c.NextReader(); err != nil {
116116+// c.Close()
117117+// break
118118+// }
119119+// }
120120+// }
121121+//
122122+// Concurrency
123123+//
124124+// Connections support one concurrent reader and one concurrent writer.
125125+//
126126+// Applications are responsible for ensuring that no more than one goroutine
127127+// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
128128+// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and
129129+// that no more than one goroutine calls the read methods (NextReader,
130130+// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)
131131+// concurrently.
132132+//
133133+// The Close and WriteControl methods can be called concurrently with all other
134134+// methods.
135135+//
136136+// Origin Considerations
137137+//
138138+// Web browsers allow Javascript applications to open a WebSocket connection to
139139+// any host. It's up to the server to enforce an origin policy using the Origin
140140+// request header sent by the browser.
141141+//
142142+// The Upgrader calls the function specified in the CheckOrigin field to check
143143+// the origin. If the CheckOrigin function returns false, then the Upgrade
144144+// method fails the WebSocket handshake with HTTP status 403.
145145+//
146146+// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
147147+// the handshake if the Origin request header is present and the Origin host is
148148+// not equal to the Host request header.
149149+//
150150+// The deprecated package-level Upgrade function does not perform origin
151151+// checking. The application is responsible for checking the Origin header
152152+// before calling the Upgrade function.
153153+//
154154+// Buffers
155155+//
156156+// Connections buffer network input and output to reduce the number
157157+// of system calls when reading or writing messages.
158158+//
159159+// Write buffers are also used for constructing WebSocket frames. See RFC 6455,
160160+// Section 5 for a discussion of message framing. A WebSocket frame header is
161161+// written to the network each time a write buffer is flushed to the network.
162162+// Decreasing the size of the write buffer can increase the amount of framing
163163+// overhead on the connection.
164164+//
165165+// The buffer sizes in bytes are specified by the ReadBufferSize and
166166+// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default
167167+// size of 4096 when a buffer size field is set to zero. The Upgrader reuses
168168+// buffers created by the HTTP server when a buffer size field is set to zero.
169169+// The HTTP server buffers have a size of 4096 at the time of this writing.
170170+//
171171+// The buffer sizes do not limit the size of a message that can be read or
172172+// written by a connection.
173173+//
174174+// Buffers are held for the lifetime of the connection by default. If the
175175+// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the
176176+// write buffer only when writing a message.
177177+//
178178+// Applications should tune the buffer sizes to balance memory use and
179179+// performance. Increasing the buffer size uses more memory, but can reduce the
180180+// number of system calls to read or write the network. In the case of writing,
181181+// increasing the buffer size can reduce the number of frame headers written to
182182+// the network.
183183+//
184184+// Some guidelines for setting buffer parameters are:
185185+//
186186+// Limit the buffer sizes to the maximum expected message size. Buffers larger
187187+// than the largest message do not provide any benefit.
188188+//
189189+// Depending on the distribution of message sizes, setting the buffer size to
190190+// a value less than the maximum expected message size can greatly reduce memory
191191+// use with a small impact on performance. Here's an example: If 99% of the
192192+// messages are smaller than 256 bytes and the maximum message size is 512
193193+// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls
194194+// than a buffer size of 512 bytes. The memory savings is 50%.
195195+//
196196+// A write buffer pool is useful when the application has a modest number
197197+// writes over a large number of connections. when buffers are pooled, a larger
198198+// buffer size has a reduced impact on total memory use and has the benefit of
199199+// reducing system calls and frame overhead.
200200+//
201201+// Compression EXPERIMENTAL
202202+//
203203+// Per message compression extensions (RFC 7692) are experimentally supported
204204+// by this package in a limited capacity. Setting the EnableCompression option
205205+// to true in Dialer or Upgrader will attempt to negotiate per message deflate
206206+// support.
207207+//
208208+// var upgrader = websocket.Upgrader{
209209+// EnableCompression: true,
210210+// }
211211+//
212212+// If compression was successfully negotiated with the connection's peer, any
213213+// message received in compressed form will be automatically decompressed.
214214+// All Read methods will return uncompressed bytes.
215215+//
216216+// Per message compression of messages written to a connection can be enabled
217217+// or disabled by calling the corresponding Conn method:
218218+//
219219+// conn.EnableWriteCompression(false)
220220+//
221221+// Currently this package does not support compression with "context takeover".
222222+// This means that messages must be compressed and decompressed in isolation,
223223+// without retaining sliding window or dictionary state across messages. For
224224+// more details refer to RFC 7692.
225225+//
226226+// Use of compression is experimental and may result in decreased performance.
227227+package websocket
+42
vendor/github.com/gorilla/websocket/join.go
···11+// Copyright 2019 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "io"
99+ "strings"
1010+)
1111+1212+// JoinMessages concatenates received messages to create a single io.Reader.
1313+// The string term is appended to each message. The returned reader does not
1414+// support concurrent calls to the Read method.
1515+func JoinMessages(c *Conn, term string) io.Reader {
1616+ return &joinReader{c: c, term: term}
1717+}
1818+1919+type joinReader struct {
2020+ c *Conn
2121+ term string
2222+ r io.Reader
2323+}
2424+2525+func (r *joinReader) Read(p []byte) (int, error) {
2626+ if r.r == nil {
2727+ var err error
2828+ _, r.r, err = r.c.NextReader()
2929+ if err != nil {
3030+ return 0, err
3131+ }
3232+ if r.term != "" {
3333+ r.r = io.MultiReader(r.r, strings.NewReader(r.term))
3434+ }
3535+ }
3636+ n, err := r.r.Read(p)
3737+ if err == io.EOF {
3838+ err = nil
3939+ r.r = nil
4040+ }
4141+ return n, err
4242+}
+60
vendor/github.com/gorilla/websocket/json.go
···11+// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "encoding/json"
99+ "io"
1010+)
1111+1212+// WriteJSON writes the JSON encoding of v as a message.
1313+//
1414+// Deprecated: Use c.WriteJSON instead.
1515+func WriteJSON(c *Conn, v interface{}) error {
1616+ return c.WriteJSON(v)
1717+}
1818+1919+// WriteJSON writes the JSON encoding of v as a message.
2020+//
2121+// See the documentation for encoding/json Marshal for details about the
2222+// conversion of Go values to JSON.
2323+func (c *Conn) WriteJSON(v interface{}) error {
2424+ w, err := c.NextWriter(TextMessage)
2525+ if err != nil {
2626+ return err
2727+ }
2828+ err1 := json.NewEncoder(w).Encode(v)
2929+ err2 := w.Close()
3030+ if err1 != nil {
3131+ return err1
3232+ }
3333+ return err2
3434+}
3535+3636+// ReadJSON reads the next JSON-encoded message from the connection and stores
3737+// it in the value pointed to by v.
3838+//
3939+// Deprecated: Use c.ReadJSON instead.
4040+func ReadJSON(c *Conn, v interface{}) error {
4141+ return c.ReadJSON(v)
4242+}
4343+4444+// ReadJSON reads the next JSON-encoded message from the connection and stores
4545+// it in the value pointed to by v.
4646+//
4747+// See the documentation for the encoding/json Unmarshal function for details
4848+// about the conversion of JSON to a Go value.
4949+func (c *Conn) ReadJSON(v interface{}) error {
5050+ _, r, err := c.NextReader()
5151+ if err != nil {
5252+ return err
5353+ }
5454+ err = json.NewDecoder(r).Decode(v)
5555+ if err == io.EOF {
5656+ // One value is expected in the message.
5757+ err = io.ErrUnexpectedEOF
5858+ }
5959+ return err
6060+}
+55
vendor/github.com/gorilla/websocket/mask.go
···11+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
22+// this source code is governed by a BSD-style license that can be found in the
33+// LICENSE file.
44+55+//go:build !appengine
66+// +build !appengine
77+88+package websocket
99+1010+import "unsafe"
1111+1212+const wordSize = int(unsafe.Sizeof(uintptr(0)))
1313+1414+func maskBytes(key [4]byte, pos int, b []byte) int {
1515+ // Mask one byte at a time for small buffers.
1616+ if len(b) < 2*wordSize {
1717+ for i := range b {
1818+ b[i] ^= key[pos&3]
1919+ pos++
2020+ }
2121+ return pos & 3
2222+ }
2323+2424+ // Mask one byte at a time to word boundary.
2525+ if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
2626+ n = wordSize - n
2727+ for i := range b[:n] {
2828+ b[i] ^= key[pos&3]
2929+ pos++
3030+ }
3131+ b = b[n:]
3232+ }
3333+3434+ // Create aligned word size key.
3535+ var k [wordSize]byte
3636+ for i := range k {
3737+ k[i] = key[(pos+i)&3]
3838+ }
3939+ kw := *(*uintptr)(unsafe.Pointer(&k))
4040+4141+ // Mask one word at a time.
4242+ n := (len(b) / wordSize) * wordSize
4343+ for i := 0; i < n; i += wordSize {
4444+ *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw
4545+ }
4646+4747+ // Mask one byte at a time for remaining bytes.
4848+ b = b[n:]
4949+ for i := range b {
5050+ b[i] ^= key[pos&3]
5151+ pos++
5252+ }
5353+5454+ return pos & 3
5555+}
+16
vendor/github.com/gorilla/websocket/mask_safe.go
···11+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
22+// this source code is governed by a BSD-style license that can be found in the
33+// LICENSE file.
44+55+//go:build appengine
66+// +build appengine
77+88+package websocket
99+1010+func maskBytes(key [4]byte, pos int, b []byte) int {
1111+ for i := range b {
1212+ b[i] ^= key[pos&3]
1313+ pos++
1414+ }
1515+ return pos & 3
1616+}
+102
vendor/github.com/gorilla/websocket/prepared.go
···11+// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "bytes"
99+ "net"
1010+ "sync"
1111+ "time"
1212+)
1313+1414+// PreparedMessage caches on the wire representations of a message payload.
1515+// Use PreparedMessage to efficiently send a message payload to multiple
1616+// connections. PreparedMessage is especially useful when compression is used
1717+// because the CPU and memory expensive compression operation can be executed
1818+// once for a given set of compression options.
1919+type PreparedMessage struct {
2020+ messageType int
2121+ data []byte
2222+ mu sync.Mutex
2323+ frames map[prepareKey]*preparedFrame
2424+}
2525+2626+// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage.
2727+type prepareKey struct {
2828+ isServer bool
2929+ compress bool
3030+ compressionLevel int
3131+}
3232+3333+// preparedFrame contains data in wire representation.
3434+type preparedFrame struct {
3535+ once sync.Once
3636+ data []byte
3737+}
3838+3939+// NewPreparedMessage returns an initialized PreparedMessage. You can then send
4040+// it to connection using WritePreparedMessage method. Valid wire
4141+// representation will be calculated lazily only once for a set of current
4242+// connection options.
4343+func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {
4444+ pm := &PreparedMessage{
4545+ messageType: messageType,
4646+ frames: make(map[prepareKey]*preparedFrame),
4747+ data: data,
4848+ }
4949+5050+ // Prepare a plain server frame.
5151+ _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})
5252+ if err != nil {
5353+ return nil, err
5454+ }
5555+5656+ // To protect against caller modifying the data argument, remember the data
5757+ // copied to the plain server frame.
5858+ pm.data = frameData[len(frameData)-len(data):]
5959+ return pm, nil
6060+}
6161+6262+func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {
6363+ pm.mu.Lock()
6464+ frame, ok := pm.frames[key]
6565+ if !ok {
6666+ frame = &preparedFrame{}
6767+ pm.frames[key] = frame
6868+ }
6969+ pm.mu.Unlock()
7070+7171+ var err error
7272+ frame.once.Do(func() {
7373+ // Prepare a frame using a 'fake' connection.
7474+ // TODO: Refactor code in conn.go to allow more direct construction of
7575+ // the frame.
7676+ mu := make(chan struct{}, 1)
7777+ mu <- struct{}{}
7878+ var nc prepareConn
7979+ c := &Conn{
8080+ conn: &nc,
8181+ mu: mu,
8282+ isServer: key.isServer,
8383+ compressionLevel: key.compressionLevel,
8484+ enableWriteCompression: true,
8585+ writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),
8686+ }
8787+ if key.compress {
8888+ c.newCompressionWriter = compressNoContextTakeover
8989+ }
9090+ err = c.WriteMessage(pm.messageType, pm.data)
9191+ frame.data = nc.buf.Bytes()
9292+ })
9393+ return pm.messageType, frame.data, err
9494+}
9595+9696+type prepareConn struct {
9797+ buf bytes.Buffer
9898+ net.Conn
9999+}
100100+101101+func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) }
102102+func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }
+77
vendor/github.com/gorilla/websocket/proxy.go
···11+// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "bufio"
99+ "encoding/base64"
1010+ "errors"
1111+ "net"
1212+ "net/http"
1313+ "net/url"
1414+ "strings"
1515+)
1616+1717+type netDialerFunc func(network, addr string) (net.Conn, error)
1818+1919+func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
2020+ return fn(network, addr)
2121+}
2222+2323+func init() {
2424+ proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
2525+ return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil
2626+ })
2727+}
2828+2929+type httpProxyDialer struct {
3030+ proxyURL *url.URL
3131+ forwardDial func(network, addr string) (net.Conn, error)
3232+}
3333+3434+func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
3535+ hostPort, _ := hostPortNoPort(hpd.proxyURL)
3636+ conn, err := hpd.forwardDial(network, hostPort)
3737+ if err != nil {
3838+ return nil, err
3939+ }
4040+4141+ connectHeader := make(http.Header)
4242+ if user := hpd.proxyURL.User; user != nil {
4343+ proxyUser := user.Username()
4444+ if proxyPassword, passwordSet := user.Password(); passwordSet {
4545+ credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
4646+ connectHeader.Set("Proxy-Authorization", "Basic "+credential)
4747+ }
4848+ }
4949+5050+ connectReq := &http.Request{
5151+ Method: http.MethodConnect,
5252+ URL: &url.URL{Opaque: addr},
5353+ Host: addr,
5454+ Header: connectHeader,
5555+ }
5656+5757+ if err := connectReq.Write(conn); err != nil {
5858+ conn.Close()
5959+ return nil, err
6060+ }
6161+6262+ // Read response. It's OK to use and discard buffered reader here becaue
6363+ // the remote server does not speak until spoken to.
6464+ br := bufio.NewReader(conn)
6565+ resp, err := http.ReadResponse(br, connectReq)
6666+ if err != nil {
6767+ conn.Close()
6868+ return nil, err
6969+ }
7070+7171+ if resp.StatusCode != 200 {
7272+ conn.Close()
7373+ f := strings.SplitN(resp.Status, " ", 2)
7474+ return nil, errors.New(f[1])
7575+ }
7676+ return conn, nil
7777+}
+365
vendor/github.com/gorilla/websocket/server.go
···11+// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
22+// Use of this source code is governed by a BSD-style
33+// license that can be found in the LICENSE file.
44+55+package websocket
66+77+import (
88+ "bufio"
99+ "errors"
1010+ "io"
1111+ "net/http"
1212+ "net/url"
1313+ "strings"
1414+ "time"
1515+)
1616+1717+// HandshakeError describes an error with the handshake from the peer.
1818+type HandshakeError struct {
1919+ message string
2020+}
2121+2222+func (e HandshakeError) Error() string { return e.message }
2323+2424+// Upgrader specifies parameters for upgrading an HTTP connection to a
2525+// WebSocket connection.
2626+//
2727+// It is safe to call Upgrader's methods concurrently.
2828+type Upgrader struct {
2929+ // HandshakeTimeout specifies the duration for the handshake to complete.
3030+ HandshakeTimeout time.Duration
3131+3232+ // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer
3333+ // size is zero, then buffers allocated by the HTTP server are used. The
3434+ // I/O buffer sizes do not limit the size of the messages that can be sent
3535+ // or received.
3636+ ReadBufferSize, WriteBufferSize int
3737+3838+ // WriteBufferPool is a pool of buffers for write operations. If the value
3939+ // is not set, then write buffers are allocated to the connection for the
4040+ // lifetime of the connection.
4141+ //
4242+ // A pool is most useful when the application has a modest volume of writes
4343+ // across a large number of connections.
4444+ //
4545+ // Applications should use a single pool for each unique value of
4646+ // WriteBufferSize.
4747+ WriteBufferPool BufferPool
4848+4949+ // Subprotocols specifies the server's supported protocols in order of
5050+ // preference. If this field is not nil, then the Upgrade method negotiates a
5151+ // subprotocol by selecting the first match in this list with a protocol
5252+ // requested by the client. If there's no match, then no protocol is
5353+ // negotiated (the Sec-Websocket-Protocol header is not included in the
5454+ // handshake response).
5555+ Subprotocols []string
5656+5757+ // Error specifies the function for generating HTTP error responses. If Error
5858+ // is nil, then http.Error is used to generate the HTTP response.
5959+ Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
6060+6161+ // CheckOrigin returns true if the request Origin header is acceptable. If
6262+ // CheckOrigin is nil, then a safe default is used: return false if the
6363+ // Origin request header is present and the origin host is not equal to
6464+ // request Host header.
6565+ //
6666+ // A CheckOrigin function should carefully validate the request origin to
6767+ // prevent cross-site request forgery.
6868+ CheckOrigin func(r *http.Request) bool
6969+7070+ // EnableCompression specify if the server should attempt to negotiate per
7171+ // message compression (RFC 7692). Setting this value to true does not
7272+ // guarantee that compression will be supported. Currently only "no context
7373+ // takeover" modes are supported.
7474+ EnableCompression bool
7575+}
7676+7777+func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
7878+ err := HandshakeError{reason}
7979+ if u.Error != nil {
8080+ u.Error(w, r, status, err)
8181+ } else {
8282+ w.Header().Set("Sec-Websocket-Version", "13")
8383+ http.Error(w, http.StatusText(status), status)
8484+ }
8585+ return nil, err
8686+}
8787+8888+// checkSameOrigin returns true if the origin is not set or is equal to the request host.
8989+func checkSameOrigin(r *http.Request) bool {
9090+ origin := r.Header["Origin"]
9191+ if len(origin) == 0 {
9292+ return true
9393+ }
9494+ u, err := url.Parse(origin[0])
9595+ if err != nil {
9696+ return false
9797+ }
9898+ return equalASCIIFold(u.Host, r.Host)
9999+}
100100+101101+func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
102102+ if u.Subprotocols != nil {
103103+ clientProtocols := Subprotocols(r)
104104+ for _, serverProtocol := range u.Subprotocols {
105105+ for _, clientProtocol := range clientProtocols {
106106+ if clientProtocol == serverProtocol {
107107+ return clientProtocol
108108+ }
109109+ }
110110+ }
111111+ } else if responseHeader != nil {
112112+ return responseHeader.Get("Sec-Websocket-Protocol")
113113+ }
114114+ return ""
115115+}
116116+117117+// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
118118+//
119119+// The responseHeader is included in the response to the client's upgrade
120120+// request. Use the responseHeader to specify cookies (Set-Cookie). To specify
121121+// subprotocols supported by the server, set Upgrader.Subprotocols directly.
122122+//
123123+// If the upgrade fails, then Upgrade replies to the client with an HTTP error
124124+// response.
125125+func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
126126+ const badHandshake = "websocket: the client is not using the websocket protocol: "
127127+128128+ if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
129129+ return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header")
130130+ }
131131+132132+ if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
133133+ return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header")
134134+ }
135135+136136+ if r.Method != http.MethodGet {
137137+ return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET")
138138+ }
139139+140140+ if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") {
141141+ return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header")
142142+ }
143143+144144+ if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
145145+ return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported")
146146+ }
147147+148148+ checkOrigin := u.CheckOrigin
149149+ if checkOrigin == nil {
150150+ checkOrigin = checkSameOrigin
151151+ }
152152+ if !checkOrigin(r) {
153153+ return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin")
154154+ }
155155+156156+ challengeKey := r.Header.Get("Sec-Websocket-Key")
157157+ if !isValidChallengeKey(challengeKey) {
158158+ return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header must be Base64 encoded value of 16-byte in length")
159159+ }
160160+161161+ subprotocol := u.selectSubprotocol(r, responseHeader)
162162+163163+ // Negotiate PMCE
164164+ var compress bool
165165+ if u.EnableCompression {
166166+ for _, ext := range parseExtensions(r.Header) {
167167+ if ext[""] != "permessage-deflate" {
168168+ continue
169169+ }
170170+ compress = true
171171+ break
172172+ }
173173+ }
174174+175175+ h, ok := w.(http.Hijacker)
176176+ if !ok {
177177+ return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
178178+ }
179179+ var brw *bufio.ReadWriter
180180+ netConn, brw, err := h.Hijack()
181181+ if err != nil {
182182+ return u.returnError(w, r, http.StatusInternalServerError, err.Error())
183183+ }
184184+185185+ if brw.Reader.Buffered() > 0 {
186186+ netConn.Close()
187187+ return nil, errors.New("websocket: client sent data before handshake is complete")
188188+ }
189189+190190+ var br *bufio.Reader
191191+ if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 {
192192+ // Reuse hijacked buffered reader as connection reader.
193193+ br = brw.Reader
194194+ }
195195+196196+ buf := bufioWriterBuffer(netConn, brw.Writer)
197197+198198+ var writeBuf []byte
199199+ if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 {
200200+ // Reuse hijacked write buffer as connection buffer.
201201+ writeBuf = buf
202202+ }
203203+204204+ c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf)
205205+ c.subprotocol = subprotocol
206206+207207+ if compress {
208208+ c.newCompressionWriter = compressNoContextTakeover
209209+ c.newDecompressionReader = decompressNoContextTakeover
210210+ }
211211+212212+ // Use larger of hijacked buffer and connection write buffer for header.
213213+ p := buf
214214+ if len(c.writeBuf) > len(p) {
215215+ p = c.writeBuf
216216+ }
217217+ p = p[:0]
218218+219219+ p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
220220+ p = append(p, computeAcceptKey(challengeKey)...)
221221+ p = append(p, "\r\n"...)
222222+ if c.subprotocol != "" {
223223+ p = append(p, "Sec-WebSocket-Protocol: "...)
224224+ p = append(p, c.subprotocol...)
225225+ p = append(p, "\r\n"...)
226226+ }
227227+ if compress {
228228+ p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
229229+ }
230230+ for k, vs := range responseHeader {
231231+ if k == "Sec-Websocket-Protocol" {
232232+ continue
233233+ }
234234+ for _, v := range vs {
235235+ p = append(p, k...)
236236+ p = append(p, ": "...)
237237+ for i := 0; i < len(v); i++ {
238238+ b := v[i]
239239+ if b <= 31 {
240240+ // prevent response splitting.
241241+ b = ' '
242242+ }
243243+ p = append(p, b)
244244+ }
245245+ p = append(p, "\r\n"...)
246246+ }
247247+ }
248248+ p = append(p, "\r\n"...)
249249+250250+ // Clear deadlines set by HTTP server.
251251+ netConn.SetDeadline(time.Time{})
252252+253253+ if u.HandshakeTimeout > 0 {
254254+ netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))
255255+ }
256256+ if _, err = netConn.Write(p); err != nil {
257257+ netConn.Close()
258258+ return nil, err
259259+ }
260260+ if u.HandshakeTimeout > 0 {
261261+ netConn.SetWriteDeadline(time.Time{})
262262+ }
263263+264264+ return c, nil
265265+}
266266+267267+// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
268268+//
269269+// Deprecated: Use websocket.Upgrader instead.
270270+//
271271+// Upgrade does not perform origin checking. The application is responsible for
272272+// checking the Origin header before calling Upgrade. An example implementation
273273+// of the same origin policy check is:
274274+//
275275+// if req.Header.Get("Origin") != "http://"+req.Host {
276276+// http.Error(w, "Origin not allowed", http.StatusForbidden)
277277+// return
278278+// }
279279+//
280280+// If the endpoint supports subprotocols, then the application is responsible
281281+// for negotiating the protocol used on the connection. Use the Subprotocols()
282282+// function to get the subprotocols requested by the client. Use the
283283+// Sec-Websocket-Protocol response header to specify the subprotocol selected
284284+// by the application.
285285+//
286286+// The responseHeader is included in the response to the client's upgrade
287287+// request. Use the responseHeader to specify cookies (Set-Cookie) and the
288288+// negotiated subprotocol (Sec-Websocket-Protocol).
289289+//
290290+// The connection buffers IO to the underlying network connection. The
291291+// readBufSize and writeBufSize parameters specify the size of the buffers to
292292+// use. Messages can be larger than the buffers.
293293+//
294294+// If the request is not a valid WebSocket handshake, then Upgrade returns an
295295+// error of type HandshakeError. Applications should handle this error by
296296+// replying to the client with an HTTP error response.
297297+func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {
298298+ u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}
299299+ u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {
300300+ // don't return errors to maintain backwards compatibility
301301+ }
302302+ u.CheckOrigin = func(r *http.Request) bool {
303303+ // allow all connections by default
304304+ return true
305305+ }
306306+ return u.Upgrade(w, r, responseHeader)
307307+}
308308+309309+// Subprotocols returns the subprotocols requested by the client in the
310310+// Sec-Websocket-Protocol header.
311311+func Subprotocols(r *http.Request) []string {
312312+ h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol"))
313313+ if h == "" {
314314+ return nil
315315+ }
316316+ protocols := strings.Split(h, ",")
317317+ for i := range protocols {
318318+ protocols[i] = strings.TrimSpace(protocols[i])
319319+ }
320320+ return protocols
321321+}
322322+323323+// IsWebSocketUpgrade returns true if the client requested upgrade to the
324324+// WebSocket protocol.
325325+func IsWebSocketUpgrade(r *http.Request) bool {
326326+ return tokenListContainsValue(r.Header, "Connection", "upgrade") &&
327327+ tokenListContainsValue(r.Header, "Upgrade", "websocket")
328328+}
329329+330330+// bufioReaderSize size returns the size of a bufio.Reader.
331331+func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int {
332332+ // This code assumes that peek on a reset reader returns
333333+ // bufio.Reader.buf[:0].
334334+ // TODO: Use bufio.Reader.Size() after Go 1.10
335335+ br.Reset(originalReader)
336336+ if p, err := br.Peek(0); err == nil {
337337+ return cap(p)
338338+ }
339339+ return 0
340340+}
341341+342342+// writeHook is an io.Writer that records the last slice passed to it vio
343343+// io.Writer.Write.
344344+type writeHook struct {
345345+ p []byte
346346+}
347347+348348+func (wh *writeHook) Write(p []byte) (int, error) {
349349+ wh.p = p
350350+ return len(p), nil
351351+}
352352+353353+// bufioWriterBuffer grabs the buffer from a bufio.Writer.
354354+func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {
355355+ // This code assumes that bufio.Writer.buf[:1] is passed to the
356356+ // bufio.Writer's underlying writer.
357357+ var wh writeHook
358358+ bw.Reset(&wh)
359359+ bw.WriteByte(0)
360360+ bw.Flush()
361361+362362+ bw.Reset(originalWriter)
363363+364364+ return wh.p[:cap(wh.p)]
365365+}