summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/gorilla/websocket
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/gorilla/websocket')
-rw-r--r--vendor/github.com/gorilla/websocket/.gitignore2
-rw-r--r--vendor/github.com/gorilla/websocket/.travis.yml11
-rw-r--r--vendor/github.com/gorilla/websocket/README.md2
-rw-r--r--vendor/github.com/gorilla/websocket/client.go12
-rw-r--r--vendor/github.com/gorilla/websocket/client_server_test.go602
-rw-r--r--vendor/github.com/gorilla/websocket/client_test.go32
-rw-r--r--vendor/github.com/gorilla/websocket/compression_test.go80
-rw-r--r--vendor/github.com/gorilla/websocket/conn.go17
-rw-r--r--vendor/github.com/gorilla/websocket/conn_broadcast_test.go134
-rw-r--r--vendor/github.com/gorilla/websocket/conn_test.go496
-rw-r--r--vendor/github.com/gorilla/websocket/conn_write.go15
-rw-r--r--vendor/github.com/gorilla/websocket/conn_write_legacy.go18
-rw-r--r--vendor/github.com/gorilla/websocket/example_test.go46
-rw-r--r--vendor/github.com/gorilla/websocket/examples/autobahn/README.md13
-rw-r--r--vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json15
-rw-r--r--vendor/github.com/gorilla/websocket/examples/autobahn/server.go265
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/README.md102
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/client.go137
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/home.html98
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/hub.go53
-rw-r--r--vendor/github.com/gorilla/websocket/examples/chat/main.go40
-rw-r--r--vendor/github.com/gorilla/websocket/examples/command/README.md19
-rw-r--r--vendor/github.com/gorilla/websocket/examples/command/home.html102
-rw-r--r--vendor/github.com/gorilla/websocket/examples/command/main.go193
-rw-r--r--vendor/github.com/gorilla/websocket/examples/echo/README.md17
-rw-r--r--vendor/github.com/gorilla/websocket/examples/echo/client.go81
-rw-r--r--vendor/github.com/gorilla/websocket/examples/echo/server.go133
-rw-r--r--vendor/github.com/gorilla/websocket/examples/filewatch/README.md9
-rw-r--r--vendor/github.com/gorilla/websocket/examples/filewatch/main.go193
-rw-r--r--vendor/github.com/gorilla/websocket/json_test.go119
-rw-r--r--vendor/github.com/gorilla/websocket/mask_test.go73
-rw-r--r--vendor/github.com/gorilla/websocket/prepared_test.go74
-rw-r--r--vendor/github.com/gorilla/websocket/server.go2
-rw-r--r--vendor/github.com/gorilla/websocket/server_test.go69
-rw-r--r--vendor/github.com/gorilla/websocket/util_test.go95
35 files changed, 58 insertions, 3311 deletions
diff --git a/vendor/github.com/gorilla/websocket/.gitignore b/vendor/github.com/gorilla/websocket/.gitignore
index ac710204f..cd3fcd1ef 100644
--- a/vendor/github.com/gorilla/websocket/.gitignore
+++ b/vendor/github.com/gorilla/websocket/.gitignore
@@ -22,4 +22,4 @@ _testmain.go
*.exe
.idea/
-*.iml \ No newline at end of file
+*.iml
diff --git a/vendor/github.com/gorilla/websocket/.travis.yml b/vendor/github.com/gorilla/websocket/.travis.yml
index 9f233f983..1f730470a 100644
--- a/vendor/github.com/gorilla/websocket/.travis.yml
+++ b/vendor/github.com/gorilla/websocket/.travis.yml
@@ -4,11 +4,12 @@ sudo: false
matrix:
include:
- go: 1.4
- - go: 1.5
- - go: 1.6
- - go: 1.7
- - go: 1.8
- - go: 1.9
+ - go: 1.5.x
+ - go: 1.6.x
+ - go: 1.7.x
+ - go: 1.8.x
+ - go: 1.9.x
+ - go: 1.10.x
- go: tip
allow_failures:
- go: tip
diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md
index 33c3d2be3..20e391f86 100644
--- a/vendor/github.com/gorilla/websocket/README.md
+++ b/vendor/github.com/gorilla/websocket/README.md
@@ -51,7 +51,7 @@ subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn
<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
</table>
-Notes:
+Notes:
1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
2. The application can get the type of a received data message by implementing
diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go
index 934e28e96..8e90de27f 100644
--- a/vendor/github.com/gorilla/websocket/client.go
+++ b/vendor/github.com/gorilla/websocket/client.go
@@ -106,9 +106,13 @@ func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
// DefaultDialer is a dialer with all fields set to the default values.
var DefaultDialer = &Dialer{
- Proxy: http.ProxyFromEnvironment,
+ Proxy: http.ProxyFromEnvironment,
+ HandshakeTimeout: 45 * time.Second,
}
+// nilDialer is dialer to use when receiver is nil.
+var nilDialer Dialer = *DefaultDialer
+
// Dial creates a new client connection. Use requestHeader to specify the
// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
// Use the response.Header to get the selected subprotocol
@@ -121,9 +125,7 @@ var DefaultDialer = &Dialer{
func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
if d == nil {
- d = &Dialer{
- Proxy: http.ProxyFromEnvironment,
- }
+ d = &nilDialer
}
challengeKey, err := generateChallengeKey()
@@ -191,6 +193,8 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
k == "Sec-Websocket-Extensions" ||
(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
+ case k == "Sec-Websocket-Protocol":
+ req.Header["Sec-WebSocket-Protocol"] = vs
default:
req.Header[k] = vs
}
diff --git a/vendor/github.com/gorilla/websocket/client_server_test.go b/vendor/github.com/gorilla/websocket/client_server_test.go
deleted file mode 100644
index 50063b7e0..000000000
--- a/vendor/github.com/gorilla/websocket/client_server_test.go
+++ /dev/null
@@ -1,602 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "bytes"
- "crypto/tls"
- "crypto/x509"
- "encoding/base64"
- "encoding/binary"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "net/http/cookiejar"
- "net/http/httptest"
- "net/url"
- "reflect"
- "strings"
- "testing"
- "time"
-)
-
-var cstUpgrader = Upgrader{
- Subprotocols: []string{"p0", "p1"},
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- EnableCompression: true,
- Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {
- http.Error(w, reason.Error(), status)
- },
-}
-
-var cstDialer = Dialer{
- Subprotocols: []string{"p1", "p2"},
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- HandshakeTimeout: 30 * time.Second,
-}
-
-type cstHandler struct{ *testing.T }
-
-type cstServer struct {
- *httptest.Server
- URL string
-}
-
-const (
- cstPath = "/a/b"
- cstRawQuery = "x=y"
- cstRequestURI = cstPath + "?" + cstRawQuery
-)
-
-func newServer(t *testing.T) *cstServer {
- var s cstServer
- s.Server = httptest.NewServer(cstHandler{t})
- s.Server.URL += cstRequestURI
- s.URL = makeWsProto(s.Server.URL)
- return &s
-}
-
-func newTLSServer(t *testing.T) *cstServer {
- var s cstServer
- s.Server = httptest.NewTLSServer(cstHandler{t})
- s.Server.URL += cstRequestURI
- s.URL = makeWsProto(s.Server.URL)
- return &s
-}
-
-func (t cstHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != cstPath {
- t.Logf("path=%v, want %v", r.URL.Path, cstPath)
- http.Error(w, "bad path", 400)
- return
- }
- if r.URL.RawQuery != cstRawQuery {
- t.Logf("query=%v, want %v", r.URL.RawQuery, cstRawQuery)
- http.Error(w, "bad path", 400)
- return
- }
- subprotos := Subprotocols(r)
- if !reflect.DeepEqual(subprotos, cstDialer.Subprotocols) {
- t.Logf("subprotols=%v, want %v", subprotos, cstDialer.Subprotocols)
- http.Error(w, "bad protocol", 400)
- return
- }
- ws, err := cstUpgrader.Upgrade(w, r, http.Header{"Set-Cookie": {"sessionID=1234"}})
- if err != nil {
- t.Logf("Upgrade: %v", err)
- return
- }
- defer ws.Close()
-
- if ws.Subprotocol() != "p1" {
- t.Logf("Subprotocol() = %s, want p1", ws.Subprotocol())
- ws.Close()
- return
- }
- op, rd, err := ws.NextReader()
- if err != nil {
- t.Logf("NextReader: %v", err)
- return
- }
- wr, err := ws.NextWriter(op)
- if err != nil {
- t.Logf("NextWriter: %v", err)
- return
- }
- if _, err = io.Copy(wr, rd); err != nil {
- t.Logf("NextWriter: %v", err)
- return
- }
- if err := wr.Close(); err != nil {
- t.Logf("Close: %v", err)
- return
- }
-}
-
-func makeWsProto(s string) string {
- return "ws" + strings.TrimPrefix(s, "http")
-}
-
-func sendRecv(t *testing.T, ws *Conn) {
- const message = "Hello World!"
- if err := ws.SetWriteDeadline(time.Now().Add(time.Second)); err != nil {
- t.Fatalf("SetWriteDeadline: %v", err)
- }
- if err := ws.WriteMessage(TextMessage, []byte(message)); err != nil {
- t.Fatalf("WriteMessage: %v", err)
- }
- if err := ws.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
- t.Fatalf("SetReadDeadline: %v", err)
- }
- _, p, err := ws.ReadMessage()
- if err != nil {
- t.Fatalf("ReadMessage: %v", err)
- }
- if string(p) != message {
- t.Fatalf("message=%s, want %s", p, message)
- }
-}
-
-func TestProxyDial(t *testing.T) {
-
- s := newServer(t)
- defer s.Close()
-
- surl, _ := url.Parse(s.Server.URL)
-
- cstDialer := cstDialer // make local copy for modification on next line.
- cstDialer.Proxy = http.ProxyURL(surl)
-
- connect := false
- origHandler := s.Server.Config.Handler
-
- // Capture the request Host header.
- s.Server.Config.Handler = http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- if r.Method == "CONNECT" {
- connect = true
- w.WriteHeader(200)
- return
- }
-
- if !connect {
- t.Log("connect not received")
- http.Error(w, "connect not received", 405)
- return
- }
- origHandler.ServeHTTP(w, r)
- })
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestProxyAuthorizationDial(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- surl, _ := url.Parse(s.Server.URL)
- surl.User = url.UserPassword("username", "password")
-
- cstDialer := cstDialer // make local copy for modification on next line.
- cstDialer.Proxy = http.ProxyURL(surl)
-
- connect := false
- origHandler := s.Server.Config.Handler
-
- // Capture the request Host header.
- s.Server.Config.Handler = http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- proxyAuth := r.Header.Get("Proxy-Authorization")
- expectedProxyAuth := "Basic " + base64.StdEncoding.EncodeToString([]byte("username:password"))
- if r.Method == "CONNECT" && proxyAuth == expectedProxyAuth {
- connect = true
- w.WriteHeader(200)
- return
- }
-
- if !connect {
- t.Log("connect with proxy authorization not received")
- http.Error(w, "connect with proxy authorization not received", 405)
- return
- }
- origHandler.ServeHTTP(w, r)
- })
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestDial(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestDialCookieJar(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- jar, _ := cookiejar.New(nil)
- d := cstDialer
- d.Jar = jar
-
- u, _ := url.Parse(s.URL)
-
- switch u.Scheme {
- case "ws":
- u.Scheme = "http"
- case "wss":
- u.Scheme = "https"
- }
-
- cookies := []*http.Cookie{{Name: "gorilla", Value: "ws", Path: "/"}}
- d.Jar.SetCookies(u, cookies)
-
- ws, _, err := d.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
-
- var gorilla string
- var sessionID string
- for _, c := range d.Jar.Cookies(u) {
- if c.Name == "gorilla" {
- gorilla = c.Value
- }
-
- if c.Name == "sessionID" {
- sessionID = c.Value
- }
- }
- if gorilla != "ws" {
- t.Error("Cookie not present in jar.")
- }
-
- if sessionID != "1234" {
- t.Error("Set-Cookie not received from the server.")
- }
-
- sendRecv(t, ws)
-}
-
-func TestDialTLS(t *testing.T) {
- s := newTLSServer(t)
- defer s.Close()
-
- certs := x509.NewCertPool()
- for _, c := range s.TLS.Certificates {
- roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
- if err != nil {
- t.Fatalf("error parsing server's root cert: %v", err)
- }
- for _, root := range roots {
- certs.AddCert(root)
- }
- }
-
- d := cstDialer
- d.TLSClientConfig = &tls.Config{RootCAs: certs}
- ws, _, err := d.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func xTestDialTLSBadCert(t *testing.T) {
- // This test is deactivated because of noisy logging from the net/http package.
- s := newTLSServer(t)
- defer s.Close()
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-}
-
-func TestDialTLSNoVerify(t *testing.T) {
- s := newTLSServer(t)
- defer s.Close()
-
- d := cstDialer
- d.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
- ws, _, err := d.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestDialTimeout(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- d := cstDialer
- d.HandshakeTimeout = -1
- ws, _, err := d.Dial(s.URL, nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-}
-
-func TestDialBadScheme(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, _, err := cstDialer.Dial(s.Server.URL, nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-}
-
-func TestDialBadOrigin(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {"bad"}})
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
- if resp == nil {
- t.Fatalf("resp=nil, err=%v", err)
- }
- if resp.StatusCode != http.StatusForbidden {
- t.Fatalf("status=%d, want %d", resp.StatusCode, http.StatusForbidden)
- }
-}
-
-func TestDialBadHeader(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- for _, k := range []string{"Upgrade",
- "Connection",
- "Sec-Websocket-Key",
- "Sec-Websocket-Version",
- "Sec-Websocket-Protocol"} {
- h := http.Header{}
- h.Set(k, "bad")
- ws, _, err := cstDialer.Dial(s.URL, http.Header{"Origin": {"bad"}})
- if err == nil {
- ws.Close()
- t.Errorf("Dial with header %s returned nil", k)
- }
- }
-}
-
-func TestBadMethod(t *testing.T) {
- s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- ws, err := cstUpgrader.Upgrade(w, r, nil)
- if err == nil {
- t.Errorf("handshake succeeded, expect fail")
- ws.Close()
- }
- }))
- defer s.Close()
-
- req, err := http.NewRequest("POST", s.URL, strings.NewReader(""))
- if err != nil {
- t.Fatalf("NewRequest returned error %v", err)
- }
- req.Header.Set("Connection", "upgrade")
- req.Header.Set("Upgrade", "websocket")
- req.Header.Set("Sec-Websocket-Version", "13")
-
- resp, err := http.DefaultClient.Do(req)
- if err != nil {
- t.Fatalf("Do returned error %v", err)
- }
- resp.Body.Close()
- if resp.StatusCode != http.StatusMethodNotAllowed {
- t.Errorf("Status = %d, want %d", resp.StatusCode, http.StatusMethodNotAllowed)
- }
-}
-
-func TestHandshake(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Origin": {s.URL}})
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
-
- var sessionID string
- for _, c := range resp.Cookies() {
- if c.Name == "sessionID" {
- sessionID = c.Value
- }
- }
- if sessionID != "1234" {
- t.Error("Set-Cookie not received from the server.")
- }
-
- if ws.Subprotocol() != "p1" {
- t.Errorf("ws.Subprotocol() = %s, want p1", ws.Subprotocol())
- }
- sendRecv(t, ws)
-}
-
-func TestRespOnBadHandshake(t *testing.T) {
- const expectedStatus = http.StatusGone
- const expectedBody = "This is the response body."
-
- s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(expectedStatus)
- io.WriteString(w, expectedBody)
- }))
- defer s.Close()
-
- ws, resp, err := cstDialer.Dial(makeWsProto(s.URL), nil)
- if err == nil {
- ws.Close()
- t.Fatalf("Dial: nil")
- }
-
- if resp == nil {
- t.Fatalf("resp=nil, err=%v", err)
- }
-
- if resp.StatusCode != expectedStatus {
- t.Errorf("resp.StatusCode=%d, want %d", resp.StatusCode, expectedStatus)
- }
-
- p, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- t.Fatalf("ReadFull(resp.Body) returned error %v", err)
- }
-
- if string(p) != expectedBody {
- t.Errorf("resp.Body=%s, want %s", p, expectedBody)
- }
-}
-
-// TestHostHeader confirms that the host header provided in the call to Dial is
-// sent to the server.
-func TestHostHeader(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- specifiedHost := make(chan string, 1)
- origHandler := s.Server.Config.Handler
-
- // Capture the request Host header.
- s.Server.Config.Handler = http.HandlerFunc(
- func(w http.ResponseWriter, r *http.Request) {
- specifiedHost <- r.Host
- origHandler.ServeHTTP(w, r)
- })
-
- ws, _, err := cstDialer.Dial(s.URL, http.Header{"Host": {"testhost"}})
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
-
- if gotHost := <-specifiedHost; gotHost != "testhost" {
- t.Fatalf("gotHost = %q, want \"testhost\"", gotHost)
- }
-
- sendRecv(t, ws)
-}
-
-func TestDialCompression(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- dialer := cstDialer
- dialer.EnableCompression = true
- ws, _, err := dialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
-
-func TestSocksProxyDial(t *testing.T) {
- s := newServer(t)
- defer s.Close()
-
- proxyListener, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatalf("listen failed: %v", err)
- }
- defer proxyListener.Close()
- go func() {
- c1, err := proxyListener.Accept()
- if err != nil {
- t.Errorf("proxy accept failed: %v", err)
- return
- }
- defer c1.Close()
-
- c1.SetDeadline(time.Now().Add(30 * time.Second))
-
- buf := make([]byte, 32)
- if _, err := io.ReadFull(c1, buf[:3]); err != nil {
- t.Errorf("read failed: %v", err)
- return
- }
- if want := []byte{5, 1, 0}; !bytes.Equal(want, buf[:len(want)]) {
- t.Errorf("read %x, want %x", buf[:len(want)], want)
- }
- if _, err := c1.Write([]byte{5, 0}); err != nil {
- t.Errorf("write failed: %v", err)
- return
- }
- if _, err := io.ReadFull(c1, buf[:10]); err != nil {
- t.Errorf("read failed: %v", err)
- return
- }
- if want := []byte{5, 1, 0, 1}; !bytes.Equal(want, buf[:len(want)]) {
- t.Errorf("read %x, want %x", buf[:len(want)], want)
- return
- }
- buf[1] = 0
- if _, err := c1.Write(buf[:10]); err != nil {
- t.Errorf("write failed: %v", err)
- return
- }
-
- ip := net.IP(buf[4:8])
- port := binary.BigEndian.Uint16(buf[8:10])
-
- c2, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: int(port)})
- if err != nil {
- t.Errorf("dial failed; %v", err)
- return
- }
- defer c2.Close()
- done := make(chan struct{})
- go func() {
- io.Copy(c1, c2)
- close(done)
- }()
- io.Copy(c2, c1)
- <-done
- }()
-
- purl, err := url.Parse("socks5://" + proxyListener.Addr().String())
- if err != nil {
- t.Fatalf("parse failed: %v", err)
- }
-
- cstDialer := cstDialer // make local copy for modification on next line.
- cstDialer.Proxy = http.ProxyURL(purl)
-
- ws, _, err := cstDialer.Dial(s.URL, nil)
- if err != nil {
- t.Fatalf("Dial: %v", err)
- }
- defer ws.Close()
- sendRecv(t, ws)
-}
diff --git a/vendor/github.com/gorilla/websocket/client_test.go b/vendor/github.com/gorilla/websocket/client_test.go
deleted file mode 100644
index 5aa27b37d..000000000
--- a/vendor/github.com/gorilla/websocket/client_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "net/url"
- "testing"
-)
-
-var hostPortNoPortTests = []struct {
- u *url.URL
- hostPort, hostNoPort string
-}{
- {&url.URL{Scheme: "ws", Host: "example.com"}, "example.com:80", "example.com"},
- {&url.URL{Scheme: "wss", Host: "example.com"}, "example.com:443", "example.com"},
- {&url.URL{Scheme: "ws", Host: "example.com:7777"}, "example.com:7777", "example.com"},
- {&url.URL{Scheme: "wss", Host: "example.com:7777"}, "example.com:7777", "example.com"},
-}
-
-func TestHostPortNoPort(t *testing.T) {
- for _, tt := range hostPortNoPortTests {
- hostPort, hostNoPort := hostPortNoPort(tt.u)
- if hostPort != tt.hostPort {
- t.Errorf("hostPortNoPort(%v) returned hostPort %q, want %q", tt.u, hostPort, tt.hostPort)
- }
- if hostNoPort != tt.hostNoPort {
- t.Errorf("hostPortNoPort(%v) returned hostNoPort %q, want %q", tt.u, hostNoPort, tt.hostNoPort)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/compression_test.go b/vendor/github.com/gorilla/websocket/compression_test.go
deleted file mode 100644
index 659cf4215..000000000
--- a/vendor/github.com/gorilla/websocket/compression_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package websocket
-
-import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "testing"
-)
-
-type nopCloser struct{ io.Writer }
-
-func (nopCloser) Close() error { return nil }
-
-func TestTruncWriter(t *testing.T) {
- const data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijlkmnopqrstuvwxyz987654321"
- for n := 1; n <= 10; n++ {
- var b bytes.Buffer
- w := &truncWriter{w: nopCloser{&b}}
- p := []byte(data)
- for len(p) > 0 {
- m := len(p)
- if m > n {
- m = n
- }
- w.Write(p[:m])
- p = p[m:]
- }
- if b.String() != data[:len(data)-len(w.p)] {
- t.Errorf("%d: %q", n, b.String())
- }
- }
-}
-
-func textMessages(num int) [][]byte {
- messages := make([][]byte, num)
- for i := 0; i < num; i++ {
- msg := fmt.Sprintf("planet: %d, country: %d, city: %d, street: %d", i, i, i, i)
- messages[i] = []byte(msg)
- }
- return messages
-}
-
-func BenchmarkWriteNoCompression(b *testing.B) {
- w := ioutil.Discard
- c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024)
- messages := textMessages(100)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- c.WriteMessage(TextMessage, messages[i%len(messages)])
- }
- b.ReportAllocs()
-}
-
-func BenchmarkWriteWithCompression(b *testing.B) {
- w := ioutil.Discard
- c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024)
- messages := textMessages(100)
- c.enableWriteCompression = true
- c.newCompressionWriter = compressNoContextTakeover
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- c.WriteMessage(TextMessage, messages[i%len(messages)])
- }
- b.ReportAllocs()
-}
-
-func TestValidCompressionLevel(t *testing.T) {
- c := newConn(fakeNetConn{}, false, 1024, 1024)
- for _, level := range []int{minCompressionLevel - 1, maxCompressionLevel + 1} {
- if err := c.SetCompressionLevel(level); err == nil {
- t.Errorf("no error for level %d", level)
- }
- }
- for _, level := range []int{minCompressionLevel, maxCompressionLevel} {
- if err := c.SetCompressionLevel(level); err != nil {
- t.Errorf("error for level %d", level)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go
index b051e9591..5f46bf4a5 100644
--- a/vendor/github.com/gorilla/websocket/conn.go
+++ b/vendor/github.com/gorilla/websocket/conn.go
@@ -370,7 +370,7 @@ func (c *Conn) writeFatal(err error) error {
return err
}
-func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
+func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {
<-c.mu
defer func() { c.mu <- true }()
@@ -382,15 +382,14 @@ func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
}
c.conn.SetWriteDeadline(deadline)
- for _, buf := range bufs {
- if len(buf) > 0 {
- _, err := c.conn.Write(buf)
- if err != nil {
- return c.writeFatal(err)
- }
- }
+ if len(buf1) == 0 {
+ _, err = c.conn.Write(buf0)
+ } else {
+ err = c.writeBufs(buf0, buf1)
+ }
+ if err != nil {
+ return c.writeFatal(err)
}
-
if frameType == CloseMessage {
c.writeFatal(ErrCloseSent)
}
diff --git a/vendor/github.com/gorilla/websocket/conn_broadcast_test.go b/vendor/github.com/gorilla/websocket/conn_broadcast_test.go
deleted file mode 100644
index 45038e488..000000000
--- a/vendor/github.com/gorilla/websocket/conn_broadcast_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7
-
-package websocket
-
-import (
- "io"
- "io/ioutil"
- "sync/atomic"
- "testing"
-)
-
-// broadcastBench allows to run broadcast benchmarks.
-// In every broadcast benchmark we create many connections, then send the same
-// message into every connection and wait for all writes complete. This emulates
-// an application where many connections listen to the same data - i.e. PUB/SUB
-// scenarios with many subscribers in one channel.
-type broadcastBench struct {
- w io.Writer
- message *broadcastMessage
- closeCh chan struct{}
- doneCh chan struct{}
- count int32
- conns []*broadcastConn
- compression bool
- usePrepared bool
-}
-
-type broadcastMessage struct {
- payload []byte
- prepared *PreparedMessage
-}
-
-type broadcastConn struct {
- conn *Conn
- msgCh chan *broadcastMessage
-}
-
-func newBroadcastConn(c *Conn) *broadcastConn {
- return &broadcastConn{
- conn: c,
- msgCh: make(chan *broadcastMessage, 1),
- }
-}
-
-func newBroadcastBench(usePrepared, compression bool) *broadcastBench {
- bench := &broadcastBench{
- w: ioutil.Discard,
- doneCh: make(chan struct{}),
- closeCh: make(chan struct{}),
- usePrepared: usePrepared,
- compression: compression,
- }
- msg := &broadcastMessage{
- payload: textMessages(1)[0],
- }
- if usePrepared {
- pm, _ := NewPreparedMessage(TextMessage, msg.payload)
- msg.prepared = pm
- }
- bench.message = msg
- bench.makeConns(10000)
- return bench
-}
-
-func (b *broadcastBench) makeConns(numConns int) {
- conns := make([]*broadcastConn, numConns)
-
- for i := 0; i < numConns; i++ {
- c := newConn(fakeNetConn{Reader: nil, Writer: b.w}, true, 1024, 1024)
- if b.compression {
- c.enableWriteCompression = true
- c.newCompressionWriter = compressNoContextTakeover
- }
- conns[i] = newBroadcastConn(c)
- go func(c *broadcastConn) {
- for {
- select {
- case msg := <-c.msgCh:
- if b.usePrepared {
- c.conn.WritePreparedMessage(msg.prepared)
- } else {
- c.conn.WriteMessage(TextMessage, msg.payload)
- }
- val := atomic.AddInt32(&b.count, 1)
- if val%int32(numConns) == 0 {
- b.doneCh <- struct{}{}
- }
- case <-b.closeCh:
- return
- }
- }
- }(conns[i])
- }
- b.conns = conns
-}
-
-func (b *broadcastBench) close() {
- close(b.closeCh)
-}
-
-func (b *broadcastBench) runOnce() {
- for _, c := range b.conns {
- c.msgCh <- b.message
- }
- <-b.doneCh
-}
-
-func BenchmarkBroadcast(b *testing.B) {
- benchmarks := []struct {
- name string
- usePrepared bool
- compression bool
- }{
- {"NoCompression", false, false},
- {"WithCompression", false, true},
- {"NoCompressionPrepared", true, false},
- {"WithCompressionPrepared", true, true},
- }
- for _, bm := range benchmarks {
- b.Run(bm.name, func(b *testing.B) {
- bench := newBroadcastBench(bm.usePrepared, bm.compression)
- defer bench.close()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- bench.runOnce()
- }
- b.ReportAllocs()
- })
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/conn_test.go b/vendor/github.com/gorilla/websocket/conn_test.go
deleted file mode 100644
index 5fda7b5ca..000000000
--- a/vendor/github.com/gorilla/websocket/conn_test.go
+++ /dev/null
@@ -1,496 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "reflect"
- "testing"
- "testing/iotest"
- "time"
-)
-
-var _ net.Error = errWriteTimeout
-
-type fakeNetConn struct {
- io.Reader
- io.Writer
-}
-
-func (c fakeNetConn) Close() error { return nil }
-func (c fakeNetConn) LocalAddr() net.Addr { return localAddr }
-func (c fakeNetConn) RemoteAddr() net.Addr { return remoteAddr }
-func (c fakeNetConn) SetDeadline(t time.Time) error { return nil }
-func (c fakeNetConn) SetReadDeadline(t time.Time) error { return nil }
-func (c fakeNetConn) SetWriteDeadline(t time.Time) error { return nil }
-
-type fakeAddr int
-
-var (
- localAddr = fakeAddr(1)
- remoteAddr = fakeAddr(2)
-)
-
-func (a fakeAddr) Network() string {
- return "net"
-}
-
-func (a fakeAddr) String() string {
- return "str"
-}
-
-func TestFraming(t *testing.T) {
- frameSizes := []int{0, 1, 2, 124, 125, 126, 127, 128, 129, 65534, 65535, 65536, 65537}
- var readChunkers = []struct {
- name string
- f func(io.Reader) io.Reader
- }{
- {"half", iotest.HalfReader},
- {"one", iotest.OneByteReader},
- {"asis", func(r io.Reader) io.Reader { return r }},
- }
- writeBuf := make([]byte, 65537)
- for i := range writeBuf {
- writeBuf[i] = byte(i)
- }
- var writers = []struct {
- name string
- f func(w io.Writer, n int) (int, error)
- }{
- {"iocopy", func(w io.Writer, n int) (int, error) {
- nn, err := io.Copy(w, bytes.NewReader(writeBuf[:n]))
- return int(nn), err
- }},
- {"write", func(w io.Writer, n int) (int, error) {
- return w.Write(writeBuf[:n])
- }},
- {"string", func(w io.Writer, n int) (int, error) {
- return io.WriteString(w, string(writeBuf[:n]))
- }},
- }
-
- for _, compress := range []bool{false, true} {
- for _, isServer := range []bool{true, false} {
- for _, chunker := range readChunkers {
-
- var connBuf bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
- rc := newConn(fakeNetConn{Reader: chunker.f(&connBuf), Writer: nil}, !isServer, 1024, 1024)
- if compress {
- wc.newCompressionWriter = compressNoContextTakeover
- rc.newDecompressionReader = decompressNoContextTakeover
- }
- for _, n := range frameSizes {
- for _, writer := range writers {
- name := fmt.Sprintf("z:%v, s:%v, r:%s, n:%d w:%s", compress, isServer, chunker.name, n, writer.name)
-
- w, err := wc.NextWriter(TextMessage)
- if err != nil {
- t.Errorf("%s: wc.NextWriter() returned %v", name, err)
- continue
- }
- nn, err := writer.f(w, n)
- if err != nil || nn != n {
- t.Errorf("%s: w.Write(writeBuf[:n]) returned %d, %v", name, nn, err)
- continue
- }
- err = w.Close()
- if err != nil {
- t.Errorf("%s: w.Close() returned %v", name, err)
- continue
- }
-
- opCode, r, err := rc.NextReader()
- if err != nil || opCode != TextMessage {
- t.Errorf("%s: NextReader() returned %d, r, %v", name, opCode, err)
- continue
- }
- rbuf, err := ioutil.ReadAll(r)
- if err != nil {
- t.Errorf("%s: ReadFull() returned rbuf, %v", name, err)
- continue
- }
-
- if len(rbuf) != n {
- t.Errorf("%s: len(rbuf) is %d, want %d", name, len(rbuf), n)
- continue
- }
-
- for i, b := range rbuf {
- if byte(i) != b {
- t.Errorf("%s: bad byte at offset %d", name, i)
- break
- }
- }
- }
- }
- }
- }
- }
-}
-
-func TestControl(t *testing.T) {
- const message = "this is a ping/pong messsage"
- for _, isServer := range []bool{true, false} {
- for _, isWriteControl := range []bool{true, false} {
- name := fmt.Sprintf("s:%v, wc:%v", isServer, isWriteControl)
- var connBuf bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
- rc := newConn(fakeNetConn{Reader: &connBuf, Writer: nil}, !isServer, 1024, 1024)
- if isWriteControl {
- wc.WriteControl(PongMessage, []byte(message), time.Now().Add(time.Second))
- } else {
- w, err := wc.NextWriter(PongMessage)
- if err != nil {
- t.Errorf("%s: wc.NextWriter() returned %v", name, err)
- continue
- }
- if _, err := w.Write([]byte(message)); err != nil {
- t.Errorf("%s: w.Write() returned %v", name, err)
- continue
- }
- if err := w.Close(); err != nil {
- t.Errorf("%s: w.Close() returned %v", name, err)
- continue
- }
- var actualMessage string
- rc.SetPongHandler(func(s string) error { actualMessage = s; return nil })
- rc.NextReader()
- if actualMessage != message {
- t.Errorf("%s: pong=%q, want %q", name, actualMessage, message)
- continue
- }
- }
- }
- }
-}
-
-func TestCloseFrameBeforeFinalMessageFrame(t *testing.T) {
- const bufSize = 512
-
- expectedErr := &CloseError{Code: CloseNormalClosure, Text: "hello"}
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(make([]byte, bufSize+bufSize/2))
- wc.WriteControl(CloseMessage, FormatCloseMessage(expectedErr.Code, expectedErr.Text), time.Now().Add(10*time.Second))
- w.Close()
-
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("NextReader() returned %d, %v", op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if !reflect.DeepEqual(err, expectedErr) {
- t.Fatalf("io.Copy() returned %v, want %v", err, expectedErr)
- }
- _, _, err = rc.NextReader()
- if !reflect.DeepEqual(err, expectedErr) {
- t.Fatalf("NextReader() returned %v, want %v", err, expectedErr)
- }
-}
-
-func TestEOFWithinFrame(t *testing.T) {
- const bufSize = 64
-
- for n := 0; ; n++ {
- var b bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b}, false, 1024, 1024)
- rc := newConn(fakeNetConn{Reader: &b, Writer: nil}, true, 1024, 1024)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(make([]byte, bufSize))
- w.Close()
-
- if n >= b.Len() {
- break
- }
- b.Truncate(n)
-
- op, r, err := rc.NextReader()
- if err == errUnexpectedEOF {
- continue
- }
- if op != BinaryMessage || err != nil {
- t.Fatalf("%d: NextReader() returned %d, %v", n, op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if err != errUnexpectedEOF {
- t.Fatalf("%d: io.Copy() returned %v, want %v", n, err, errUnexpectedEOF)
- }
- _, _, err = rc.NextReader()
- if err != errUnexpectedEOF {
- t.Fatalf("%d: NextReader() returned %v, want %v", n, err, errUnexpectedEOF)
- }
- }
-}
-
-func TestEOFBeforeFinalFrame(t *testing.T) {
- const bufSize = 512
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(make([]byte, bufSize+bufSize/2))
-
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("NextReader() returned %d, %v", op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if err != errUnexpectedEOF {
- t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
- }
- _, _, err = rc.NextReader()
- if err != errUnexpectedEOF {
- t.Fatalf("NextReader() returned %v, want %v", err, errUnexpectedEOF)
- }
-}
-
-func TestWriteAfterMessageWriterClose(t *testing.T) {
- wc := newConn(fakeNetConn{Reader: nil, Writer: &bytes.Buffer{}}, false, 1024, 1024)
- w, _ := wc.NextWriter(BinaryMessage)
- io.WriteString(w, "hello")
- if err := w.Close(); err != nil {
- t.Fatalf("unxpected error closing message writer, %v", err)
- }
-
- if _, err := io.WriteString(w, "world"); err == nil {
- t.Fatalf("no error writing after close")
- }
-
- w, _ = wc.NextWriter(BinaryMessage)
- io.WriteString(w, "hello")
-
- // close w by getting next writer
- _, err := wc.NextWriter(BinaryMessage)
- if err != nil {
- t.Fatalf("unexpected error getting next writer, %v", err)
- }
-
- if _, err := io.WriteString(w, "world"); err == nil {
- t.Fatalf("no error writing after close")
- }
-}
-
-func TestReadLimit(t *testing.T) {
-
- const readLimit = 512
- message := make([]byte, readLimit+1)
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, readLimit-2)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
- rc.SetReadLimit(readLimit)
-
- // Send message at the limit with interleaved pong.
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(message[:readLimit-1])
- wc.WriteControl(PongMessage, []byte("this is a pong"), time.Now().Add(10*time.Second))
- w.Write(message[:1])
- w.Close()
-
- // Send message larger than the limit.
- wc.WriteMessage(BinaryMessage, message[:readLimit+1])
-
- op, _, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("1: NextReader() returned %d, %v", op, err)
- }
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("2: NextReader() returned %d, %v", op, err)
- }
- _, err = io.Copy(ioutil.Discard, r)
- if err != ErrReadLimit {
- t.Fatalf("io.Copy() returned %v", err)
- }
-}
-
-func TestAddrs(t *testing.T) {
- c := newConn(&fakeNetConn{}, true, 1024, 1024)
- if c.LocalAddr() != localAddr {
- t.Errorf("LocalAddr = %v, want %v", c.LocalAddr(), localAddr)
- }
- if c.RemoteAddr() != remoteAddr {
- t.Errorf("RemoteAddr = %v, want %v", c.RemoteAddr(), remoteAddr)
- }
-}
-
-func TestUnderlyingConn(t *testing.T) {
- var b1, b2 bytes.Buffer
- fc := fakeNetConn{Reader: &b1, Writer: &b2}
- c := newConn(fc, true, 1024, 1024)
- ul := c.UnderlyingConn()
- if ul != fc {
- t.Fatalf("Underlying conn is not what it should be.")
- }
-}
-
-func TestBufioReadBytes(t *testing.T) {
- // Test calling bufio.ReadBytes for value longer than read buffer size.
-
- m := make([]byte, 512)
- m[len(m)-1] = '\n'
-
- var b1, b2 bytes.Buffer
- wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, len(m)+64, len(m)+64)
- rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, len(m)-64, len(m)-64)
-
- w, _ := wc.NextWriter(BinaryMessage)
- w.Write(m)
- w.Close()
-
- op, r, err := rc.NextReader()
- if op != BinaryMessage || err != nil {
- t.Fatalf("NextReader() returned %d, %v", op, err)
- }
-
- br := bufio.NewReader(r)
- p, err := br.ReadBytes('\n')
- if err != nil {
- t.Fatalf("ReadBytes() returned %v", err)
- }
- if len(p) != len(m) {
- t.Fatalf("read returned %d bytes, want %d bytes", len(p), len(m))
- }
-}
-
-var closeErrorTests = []struct {
- err error
- codes []int
- ok bool
-}{
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNormalClosure}, true},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived}, false},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived, CloseNormalClosure}, true},
- {errors.New("hello"), []int{CloseNormalClosure}, false},
-}
-
-func TestCloseError(t *testing.T) {
- for _, tt := range closeErrorTests {
- ok := IsCloseError(tt.err, tt.codes...)
- if ok != tt.ok {
- t.Errorf("IsCloseError(%#v, %#v) returned %v, want %v", tt.err, tt.codes, ok, tt.ok)
- }
- }
-}
-
-var unexpectedCloseErrorTests = []struct {
- err error
- codes []int
- ok bool
-}{
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNormalClosure}, false},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived}, true},
- {&CloseError{Code: CloseNormalClosure}, []int{CloseNoStatusReceived, CloseNormalClosure}, false},
- {errors.New("hello"), []int{CloseNormalClosure}, false},
-}
-
-func TestUnexpectedCloseErrors(t *testing.T) {
- for _, tt := range unexpectedCloseErrorTests {
- ok := IsUnexpectedCloseError(tt.err, tt.codes...)
- if ok != tt.ok {
- t.Errorf("IsUnexpectedCloseError(%#v, %#v) returned %v, want %v", tt.err, tt.codes, ok, tt.ok)
- }
- }
-}
-
-type blockingWriter struct {
- c1, c2 chan struct{}
-}
-
-func (w blockingWriter) Write(p []byte) (int, error) {
- // Allow main to continue
- close(w.c1)
- // Wait for panic in main
- <-w.c2
- return len(p), nil
-}
-
-func TestConcurrentWritePanic(t *testing.T) {
- w := blockingWriter{make(chan struct{}), make(chan struct{})}
- c := newConn(fakeNetConn{Reader: nil, Writer: w}, false, 1024, 1024)
- go func() {
- c.WriteMessage(TextMessage, []byte{})
- }()
-
- // wait for goroutine to block in write.
- <-w.c1
-
- defer func() {
- close(w.c2)
- if v := recover(); v != nil {
- return
- }
- }()
-
- c.WriteMessage(TextMessage, []byte{})
- t.Fatal("should not get here")
-}
-
-type failingReader struct{}
-
-func (r failingReader) Read(p []byte) (int, error) {
- return 0, io.EOF
-}
-
-func TestFailedConnectionReadPanic(t *testing.T) {
- c := newConn(fakeNetConn{Reader: failingReader{}, Writer: nil}, false, 1024, 1024)
-
- defer func() {
- if v := recover(); v != nil {
- return
- }
- }()
-
- for i := 0; i < 20000; i++ {
- c.ReadMessage()
- }
- t.Fatal("should not get here")
-}
-
-func TestBufioReuse(t *testing.T) {
- brw := bufio.NewReadWriter(bufio.NewReader(nil), bufio.NewWriter(nil))
- c := newConnBRW(nil, false, 0, 0, brw)
-
- if c.br != brw.Reader {
- t.Error("connection did not reuse bufio.Reader")
- }
-
- var wh writeHook
- brw.Writer.Reset(&wh)
- brw.WriteByte(0)
- brw.Flush()
- if &c.writeBuf[0] != &wh.p[0] {
- t.Error("connection did not reuse bufio.Writer")
- }
-
- brw = bufio.NewReadWriter(bufio.NewReaderSize(nil, 0), bufio.NewWriterSize(nil, 0))
- c = newConnBRW(nil, false, 0, 0, brw)
-
- if c.br == brw.Reader {
- t.Error("connection used bufio.Reader with small size")
- }
-
- brw.Writer.Reset(&wh)
- brw.WriteByte(0)
- brw.Flush()
- if &c.writeBuf[0] != &wh.p[0] {
- t.Error("connection used bufio.Writer with small size")
- }
-
-}
diff --git a/vendor/github.com/gorilla/websocket/conn_write.go b/vendor/github.com/gorilla/websocket/conn_write.go
new file mode 100644
index 000000000..a509a21f8
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/conn_write.go
@@ -0,0 +1,15 @@
+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.8
+
+package websocket
+
+import "net"
+
+func (c *Conn) writeBufs(bufs ...[]byte) error {
+ b := net.Buffers(bufs)
+ _, err := b.WriteTo(c.conn)
+ return err
+}
diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go
new file mode 100644
index 000000000..37edaff5a
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/conn_write_legacy.go
@@ -0,0 +1,18 @@
+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.8
+
+package websocket
+
+func (c *Conn) writeBufs(bufs ...[]byte) error {
+ for _, buf := range bufs {
+ if len(buf) > 0 {
+ if _, err := c.conn.Write(buf); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/gorilla/websocket/example_test.go b/vendor/github.com/gorilla/websocket/example_test.go
deleted file mode 100644
index 96449eac7..000000000
--- a/vendor/github.com/gorilla/websocket/example_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket_test
-
-import (
- "log"
- "net/http"
- "testing"
-
- "github.com/gorilla/websocket"
-)
-
-var (
- c *websocket.Conn
- req *http.Request
-)
-
-// The websocket.IsUnexpectedCloseError function is useful for identifying
-// application and protocol errors.
-//
-// This server application works with a client application running in the
-// browser. The client application does not explicitly close the websocket. The
-// only expected close message from the client has the code
-// websocket.CloseGoingAway. All other other close messages are likely the
-// result of an application or protocol error and are logged to aid debugging.
-func ExampleIsUnexpectedCloseError() {
-
- for {
- messageType, p, err := c.ReadMessage()
- if err != nil {
- if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
- log.Printf("error: %v, user-agent: %v", err, req.Header.Get("User-Agent"))
- }
- return
- }
- processMesage(messageType, p)
- }
-}
-
-func processMesage(mt int, p []byte) {}
-
-// TestX prevents godoc from showing this entire file in the example. Remove
-// this function when a second example is added.
-func TestX(t *testing.T) {}
diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/README.md b/vendor/github.com/gorilla/websocket/examples/autobahn/README.md
deleted file mode 100644
index 075ac1530..000000000
--- a/vendor/github.com/gorilla/websocket/examples/autobahn/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Test Server
-
-This package contains a server for the [Autobahn WebSockets Test Suite](http://autobahn.ws/testsuite).
-
-To test the server, run
-
- go run server.go
-
-and start the client test driver
-
- wstest -m fuzzingclient -s fuzzingclient.json
-
-When the client completes, it writes a report to reports/clients/index.html.
diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json b/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json
deleted file mode 100644
index aa3a0bc0a..000000000
--- a/vendor/github.com/gorilla/websocket/examples/autobahn/fuzzingclient.json
+++ /dev/null
@@ -1,15 +0,0 @@
-
-{
- "options": {"failByDrop": false},
- "outdir": "./reports/clients",
- "servers": [
- {"agent": "ReadAllWriteMessage", "url": "ws://localhost:9000/m", "options": {"version": 18}},
- {"agent": "ReadAllWritePreparedMessage", "url": "ws://localhost:9000/p", "options": {"version": 18}},
- {"agent": "ReadAllWrite", "url": "ws://localhost:9000/r", "options": {"version": 18}},
- {"agent": "CopyFull", "url": "ws://localhost:9000/f", "options": {"version": 18}},
- {"agent": "CopyWriterOnly", "url": "ws://localhost:9000/c", "options": {"version": 18}}
- ],
- "cases": ["*"],
- "exclude-cases": [],
- "exclude-agent-cases": {}
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/autobahn/server.go b/vendor/github.com/gorilla/websocket/examples/autobahn/server.go
deleted file mode 100644
index 3db880f90..000000000
--- a/vendor/github.com/gorilla/websocket/examples/autobahn/server.go
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Command server is a test server for the Autobahn WebSockets Test Suite.
-package main
-
-import (
- "errors"
- "flag"
- "io"
- "log"
- "net/http"
- "time"
- "unicode/utf8"
-
- "github.com/gorilla/websocket"
-)
-
-var upgrader = websocket.Upgrader{
- ReadBufferSize: 4096,
- WriteBufferSize: 4096,
- EnableCompression: true,
- CheckOrigin: func(r *http.Request) bool {
- return true
- },
-}
-
-// echoCopy echoes messages from the client using io.Copy.
-func echoCopy(w http.ResponseWriter, r *http.Request, writerOnly bool) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("Upgrade:", err)
- return
- }
- defer conn.Close()
- for {
- mt, r, err := conn.NextReader()
- if err != nil {
- if err != io.EOF {
- log.Println("NextReader:", err)
- }
- return
- }
- if mt == websocket.TextMessage {
- r = &validator{r: r}
- }
- w, err := conn.NextWriter(mt)
- if err != nil {
- log.Println("NextWriter:", err)
- return
- }
- if mt == websocket.TextMessage {
- r = &validator{r: r}
- }
- if writerOnly {
- _, err = io.Copy(struct{ io.Writer }{w}, r)
- } else {
- _, err = io.Copy(w, r)
- }
- if err != nil {
- if err == errInvalidUTF8 {
- conn.WriteControl(websocket.CloseMessage,
- websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
- time.Time{})
- }
- log.Println("Copy:", err)
- return
- }
- err = w.Close()
- if err != nil {
- log.Println("Close:", err)
- return
- }
- }
-}
-
-func echoCopyWriterOnly(w http.ResponseWriter, r *http.Request) {
- echoCopy(w, r, true)
-}
-
-func echoCopyFull(w http.ResponseWriter, r *http.Request) {
- echoCopy(w, r, false)
-}
-
-// echoReadAll echoes messages from the client by reading the entire message
-// with ioutil.ReadAll.
-func echoReadAll(w http.ResponseWriter, r *http.Request, writeMessage, writePrepared bool) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("Upgrade:", err)
- return
- }
- defer conn.Close()
- for {
- mt, b, err := conn.ReadMessage()
- if err != nil {
- if err != io.EOF {
- log.Println("NextReader:", err)
- }
- return
- }
- if mt == websocket.TextMessage {
- if !utf8.Valid(b) {
- conn.WriteControl(websocket.CloseMessage,
- websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, ""),
- time.Time{})
- log.Println("ReadAll: invalid utf8")
- }
- }
- if writeMessage {
- if !writePrepared {
- err = conn.WriteMessage(mt, b)
- if err != nil {
- log.Println("WriteMessage:", err)
- }
- } else {
- pm, err := websocket.NewPreparedMessage(mt, b)
- if err != nil {
- log.Println("NewPreparedMessage:", err)
- return
- }
- err = conn.WritePreparedMessage(pm)
- if err != nil {
- log.Println("WritePreparedMessage:", err)
- }
- }
- } else {
- w, err := conn.NextWriter(mt)
- if err != nil {
- log.Println("NextWriter:", err)
- return
- }
- if _, err := w.Write(b); err != nil {
- log.Println("Writer:", err)
- return
- }
- if err := w.Close(); err != nil {
- log.Println("Close:", err)
- return
- }
- }
- }
-}
-
-func echoReadAllWriter(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, false, false)
-}
-
-func echoReadAllWriteMessage(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, true, false)
-}
-
-func echoReadAllWritePreparedMessage(w http.ResponseWriter, r *http.Request) {
- echoReadAll(w, r, true, true)
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found.", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- io.WriteString(w, "<html><body>Echo Server</body></html>")
-}
-
-var addr = flag.String("addr", ":9000", "http service address")
-
-func main() {
- flag.Parse()
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/c", echoCopyWriterOnly)
- http.HandleFunc("/f", echoCopyFull)
- http.HandleFunc("/r", echoReadAllWriter)
- http.HandleFunc("/m", echoReadAllWriteMessage)
- http.HandleFunc("/p", echoReadAllWritePreparedMessage)
- err := http.ListenAndServe(*addr, nil)
- if err != nil {
- log.Fatal("ListenAndServe: ", err)
- }
-}
-
-type validator struct {
- state int
- x rune
- r io.Reader
-}
-
-var errInvalidUTF8 = errors.New("invalid utf8")
-
-func (r *validator) Read(p []byte) (int, error) {
- n, err := r.r.Read(p)
- state := r.state
- x := r.x
- for _, b := range p[:n] {
- state, x = decode(state, x, b)
- if state == utf8Reject {
- break
- }
- }
- r.state = state
- r.x = x
- if state == utf8Reject || (err == io.EOF && state != utf8Accept) {
- return n, errInvalidUTF8
- }
- return n, err
-}
-
-// UTF-8 decoder from http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
-//
-// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-var utf8d = [...]byte{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7f
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9f
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // a0..bf
- 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c0..df
- 0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // e0..ef
- 0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // f0..ff
- 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
- 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
- 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
- 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // s7..s8
-}
-
-const (
- utf8Accept = 0
- utf8Reject = 1
-)
-
-func decode(state int, x rune, b byte) (int, rune) {
- t := utf8d[b]
- if state != utf8Accept {
- x = rune(b&0x3f) | (x << 6)
- } else {
- x = rune((0xff >> t) & b)
- }
- state = int(utf8d[256+state*16+int(t)])
- return state, x
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/README.md b/vendor/github.com/gorilla/websocket/examples/chat/README.md
deleted file mode 100644
index 7baf3e328..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/README.md
+++ /dev/null
@@ -1,102 +0,0 @@
-# Chat Example
-
-This application shows how to use the
-[websocket](https://github.com/gorilla/websocket) package to implement a simple
-web chat application.
-
-## Running the example
-
-The example requires a working Go development environment. The [Getting
-Started](http://golang.org/doc/install) page describes how to install the
-development environment.
-
-Once you have Go up and running, you can download, build and run the example
-using the following commands.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/chat`
- $ go run *.go
-
-To use the chat example, open http://localhost:8080/ in your browser.
-
-## Server
-
-The server application defines two types, `Client` and `Hub`. The server
-creates an instance of the `Client` type for each websocket connection. A
-`Client` acts as an intermediary between the websocket connection and a single
-instance of the `Hub` type. The `Hub` maintains a set of registered clients and
-broadcasts messages to the clients.
-
-The application runs one goroutine for the `Hub` and two goroutines for each
-`Client`. The goroutines communicate with each other using channels. The `Hub`
-has channels for registering clients, unregistering clients and broadcasting
-messages. A `Client` has a buffered channel of outbound messages. One of the
-client's goroutines reads messages from this channel and writes the messages to
-the websocket. The other client goroutine reads messages from the websocket and
-sends them to the hub.
-
-### Hub
-
-The code for the `Hub` type is in
-[hub.go](https://github.com/gorilla/websocket/blob/master/examples/chat/hub.go).
-The application's `main` function starts the hub's `run` method as a goroutine.
-Clients send requests to the hub using the `register`, `unregister` and
-`broadcast` channels.
-
-The hub registers clients by adding the client pointer as a key in the
-`clients` map. The map value is always true.
-
-The unregister code is a little more complicated. In addition to deleting the
-client pointer from the `clients` map, the hub closes the clients's `send`
-channel to signal the client that no more messages will be sent to the client.
-
-The hub handles messages by looping over the registered clients and sending the
-message to the client's `send` channel. If the client's `send` buffer is full,
-then the hub assumes that the client is dead or stuck. In this case, the hub
-unregisters the client and closes the websocket.
-
-### Client
-
-The code for the `Client` type is in [client.go](https://github.com/gorilla/websocket/blob/master/examples/chat/client.go).
-
-The `serveWs` function is registered by the application's `main` function as
-an HTTP handler. The handler upgrades the HTTP connection to the WebSocket
-protocol, creates a client, registers the client with the hub and schedules the
-client to be unregistered using a defer statement.
-
-Next, the HTTP handler starts the client's `writePump` method as a goroutine.
-This method transfers messages from the client's send channel to the websocket
-connection. The writer method exits when the channel is closed by the hub or
-there's an error writing to the websocket connection.
-
-Finally, the HTTP handler calls the client's `readPump` method. This method
-transfers inbound messages from the websocket to the hub.
-
-WebSocket connections [support one concurrent reader and one concurrent
-writer](https://godoc.org/github.com/gorilla/websocket#hdr-Concurrency). The
-application ensures that these concurrency requirements are met by executing
-all reads from the `readPump` goroutine and all writes from the `writePump`
-goroutine.
-
-To improve efficiency under high load, the `writePump` function coalesces
-pending chat messages in the `send` channel to a single WebSocket message. This
-reduces the number of system calls and the amount of data sent over the
-network.
-
-## Frontend
-
-The frontend code is in [home.html](https://github.com/gorilla/websocket/blob/master/examples/chat/home.html).
-
-On document load, the script checks for websocket functionality in the browser.
-If websocket functionality is available, then the script opens a connection to
-the server and registers a callback to handle messages from the server. The
-callback appends the message to the chat log using the appendLog function.
-
-To allow the user to manually scroll through the chat log without interruption
-from new messages, the `appendLog` function checks the scroll position before
-adding new content. If the chat log is scrolled to the bottom, then the
-function scrolls new content into view after adding the content. Otherwise, the
-scroll position is not changed.
-
-The form handler writes the user input to the websocket and clears the input
-field.
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/client.go b/vendor/github.com/gorilla/websocket/examples/chat/client.go
deleted file mode 100644
index 9461c1ea0..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/client.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "bytes"
- "log"
- "net/http"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-const (
- // Time allowed to write a message to the peer.
- writeWait = 10 * time.Second
-
- // Time allowed to read the next pong message from the peer.
- pongWait = 60 * time.Second
-
- // Send pings to peer with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Maximum message size allowed from peer.
- maxMessageSize = 512
-)
-
-var (
- newline = []byte{'\n'}
- space = []byte{' '}
-)
-
-var upgrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
-}
-
-// Client is a middleman between the websocket connection and the hub.
-type Client struct {
- hub *Hub
-
- // The websocket connection.
- conn *websocket.Conn
-
- // Buffered channel of outbound messages.
- send chan []byte
-}
-
-// readPump pumps messages from the websocket connection to the hub.
-//
-// The application runs readPump in a per-connection goroutine. The application
-// ensures that there is at most one reader on a connection by executing all
-// reads from this goroutine.
-func (c *Client) readPump() {
- defer func() {
- c.hub.unregister <- c
- c.conn.Close()
- }()
- c.conn.SetReadLimit(maxMessageSize)
- c.conn.SetReadDeadline(time.Now().Add(pongWait))
- c.conn.SetPongHandler(func(string) error { c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, message, err := c.conn.ReadMessage()
- if err != nil {
- if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
- log.Printf("error: %v", err)
- }
- break
- }
- message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))
- c.hub.broadcast <- message
- }
-}
-
-// writePump pumps messages from the hub to the websocket connection.
-//
-// A goroutine running writePump is started for each connection. The
-// application ensures that there is at most one writer to a connection by
-// executing all writes from this goroutine.
-func (c *Client) writePump() {
- ticker := time.NewTicker(pingPeriod)
- defer func() {
- ticker.Stop()
- c.conn.Close()
- }()
- for {
- select {
- case message, ok := <-c.send:
- c.conn.SetWriteDeadline(time.Now().Add(writeWait))
- if !ok {
- // The hub closed the channel.
- c.conn.WriteMessage(websocket.CloseMessage, []byte{})
- return
- }
-
- w, err := c.conn.NextWriter(websocket.TextMessage)
- if err != nil {
- return
- }
- w.Write(message)
-
- // Add queued chat messages to the current websocket message.
- n := len(c.send)
- for i := 0; i < n; i++ {
- w.Write(newline)
- w.Write(<-c.send)
- }
-
- if err := w.Close(); err != nil {
- return
- }
- case <-ticker.C:
- c.conn.SetWriteDeadline(time.Now().Add(writeWait))
- if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
- return
- }
- }
- }
-}
-
-// serveWs handles websocket requests from the peer.
-func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
- conn, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println(err)
- return
- }
- client := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)}
- client.hub.register <- client
-
- // Allow collection of memory referenced by the caller by doing all work in
- // new goroutines.
- go client.writePump()
- go client.readPump()
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/home.html b/vendor/github.com/gorilla/websocket/examples/chat/home.html
deleted file mode 100644
index a39a0c276..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/home.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Chat Example</title>
-<script type="text/javascript">
-window.onload = function () {
- var conn;
- var msg = document.getElementById("msg");
- var log = document.getElementById("log");
-
- function appendLog(item) {
- var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
- log.appendChild(item);
- if (doScroll) {
- log.scrollTop = log.scrollHeight - log.clientHeight;
- }
- }
-
- document.getElementById("form").onsubmit = function () {
- if (!conn) {
- return false;
- }
- if (!msg.value) {
- return false;
- }
- conn.send(msg.value);
- msg.value = "";
- return false;
- };
-
- if (window["WebSocket"]) {
- conn = new WebSocket("ws://" + document.location.host + "/ws");
- conn.onclose = function (evt) {
- var item = document.createElement("div");
- item.innerHTML = "<b>Connection closed.</b>";
- appendLog(item);
- };
- conn.onmessage = function (evt) {
- var messages = evt.data.split('\n');
- for (var i = 0; i < messages.length; i++) {
- var item = document.createElement("div");
- item.innerText = messages[i];
- appendLog(item);
- }
- };
- } else {
- var item = document.createElement("div");
- item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
- appendLog(item);
- }
-};
-</script>
-<style type="text/css">
-html {
- overflow: hidden;
-}
-
-body {
- overflow: hidden;
- padding: 0;
- margin: 0;
- width: 100%;
- height: 100%;
- background: gray;
-}
-
-#log {
- background: white;
- margin: 0;
- padding: 0.5em 0.5em 0.5em 0.5em;
- position: absolute;
- top: 0.5em;
- left: 0.5em;
- right: 0.5em;
- bottom: 3em;
- overflow: auto;
-}
-
-#form {
- padding: 0 0.5em 0 0.5em;
- margin: 0;
- position: absolute;
- bottom: 1em;
- left: 0px;
- width: 100%;
- overflow: hidden;
-}
-
-</style>
-</head>
-<body>
-<div id="log"></div>
-<form id="form">
- <input type="submit" value="Send" />
- <input type="text" id="msg" size="64"/>
-</form>
-</body>
-</html>
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/hub.go b/vendor/github.com/gorilla/websocket/examples/chat/hub.go
deleted file mode 100644
index 7f07ea079..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/hub.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-// hub maintains the set of active clients and broadcasts messages to the
-// clients.
-type Hub struct {
- // Registered clients.
- clients map[*Client]bool
-
- // Inbound messages from the clients.
- broadcast chan []byte
-
- // Register requests from the clients.
- register chan *Client
-
- // Unregister requests from clients.
- unregister chan *Client
-}
-
-func newHub() *Hub {
- return &Hub{
- broadcast: make(chan []byte),
- register: make(chan *Client),
- unregister: make(chan *Client),
- clients: make(map[*Client]bool),
- }
-}
-
-func (h *Hub) run() {
- for {
- select {
- case client := <-h.register:
- h.clients[client] = true
- case client := <-h.unregister:
- if _, ok := h.clients[client]; ok {
- delete(h.clients, client)
- close(client.send)
- }
- case message := <-h.broadcast:
- for client := range h.clients {
- select {
- case client.send <- message:
- default:
- close(client.send)
- delete(h.clients, client)
- }
- }
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/chat/main.go b/vendor/github.com/gorilla/websocket/examples/chat/main.go
deleted file mode 100644
index 74615d59c..000000000
--- a/vendor/github.com/gorilla/websocket/examples/chat/main.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "flag"
- "log"
- "net/http"
-)
-
-var addr = flag.String("addr", ":8080", "http service address")
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- log.Println(r.URL)
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- http.ServeFile(w, r, "home.html")
-}
-
-func main() {
- flag.Parse()
- hub := newHub()
- go hub.run()
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
- serveWs(hub, w, r)
- })
- err := http.ListenAndServe(*addr, nil)
- if err != nil {
- log.Fatal("ListenAndServe: ", err)
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/command/README.md b/vendor/github.com/gorilla/websocket/examples/command/README.md
deleted file mode 100644
index ed6f78684..000000000
--- a/vendor/github.com/gorilla/websocket/examples/command/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Command example
-
-This example connects a websocket connection to stdin and stdout of a command.
-Received messages are written to stdin followed by a `\n`. Each line read from
-standard out is sent as a message to the client.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/command`
- $ go run main.go <command and arguments to run>
- # Open http://localhost:8080/ .
-
-Try the following commands.
-
- # Echo sent messages to the output area.
- $ go run main.go cat
-
- # Run a shell.Try sending "ls" and "cat main.go".
- $ go run main.go sh
-
diff --git a/vendor/github.com/gorilla/websocket/examples/command/home.html b/vendor/github.com/gorilla/websocket/examples/command/home.html
deleted file mode 100644
index 19c46128a..000000000
--- a/vendor/github.com/gorilla/websocket/examples/command/home.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>Command Example</title>
-<script type="text/javascript">
-window.onload = function () {
- var conn;
- var msg = document.getElementById("msg");
- var log = document.getElementById("log");
-
- function appendLog(item) {
- var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
- log.appendChild(item);
- if (doScroll) {
- log.scrollTop = log.scrollHeight - log.clientHeight;
- }
- }
-
- document.getElementById("form").onsubmit = function () {
- if (!conn) {
- return false;
- }
- if (!msg.value) {
- return false;
- }
- conn.send(msg.value);
- msg.value = "";
- return false;
- };
-
- if (window["WebSocket"]) {
- conn = new WebSocket("ws://" + document.location.host + "/ws");
- conn.onclose = function (evt) {
- var item = document.createElement("div");
- item.innerHTML = "<b>Connection closed.</b>";
- appendLog(item);
- };
- conn.onmessage = function (evt) {
- var messages = evt.data.split('\n');
- for (var i = 0; i < messages.length; i++) {
- var item = document.createElement("div");
- item.innerText = messages[i];
- appendLog(item);
- }
- };
- } else {
- var item = document.createElement("div");
- item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
- appendLog(item);
- }
-};
-</script>
-<style type="text/css">
-html {
- overflow: hidden;
-}
-
-body {
- overflow: hidden;
- padding: 0;
- margin: 0;
- width: 100%;
- height: 100%;
- background: gray;
-}
-
-#log {
- background: white;
- margin: 0;
- padding: 0.5em 0.5em 0.5em 0.5em;
- position: absolute;
- top: 0.5em;
- left: 0.5em;
- right: 0.5em;
- bottom: 3em;
- overflow: auto;
-}
-
-#log pre {
- margin: 0;
-}
-
-#form {
- padding: 0 0.5em 0 0.5em;
- margin: 0;
- position: absolute;
- bottom: 1em;
- left: 0px;
- width: 100%;
- overflow: hidden;
-}
-
-</style>
-</head>
-<body>
-<div id="log"></div>
-<form id="form">
- <input type="submit" value="Send" />
- <input type="text" id="msg" size="64"/>
-</form>
-</body>
-</html>
diff --git a/vendor/github.com/gorilla/websocket/examples/command/main.go b/vendor/github.com/gorilla/websocket/examples/command/main.go
deleted file mode 100644
index 239c5c85c..000000000
--- a/vendor/github.com/gorilla/websocket/examples/command/main.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "bufio"
- "flag"
- "io"
- "log"
- "net/http"
- "os"
- "os/exec"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-var (
- addr = flag.String("addr", "127.0.0.1:8080", "http service address")
- cmdPath string
-)
-
-const (
- // Time allowed to write a message to the peer.
- writeWait = 10 * time.Second
-
- // Maximum message size allowed from peer.
- maxMessageSize = 8192
-
- // Time allowed to read the next pong message from the peer.
- pongWait = 60 * time.Second
-
- // Send pings to peer with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Time to wait before force close on connection.
- closeGracePeriod = 10 * time.Second
-)
-
-func pumpStdin(ws *websocket.Conn, w io.Writer) {
- defer ws.Close()
- ws.SetReadLimit(maxMessageSize)
- ws.SetReadDeadline(time.Now().Add(pongWait))
- ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, message, err := ws.ReadMessage()
- if err != nil {
- break
- }
- message = append(message, '\n')
- if _, err := w.Write(message); err != nil {
- break
- }
- }
-}
-
-func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
- defer func() {
- }()
- s := bufio.NewScanner(r)
- for s.Scan() {
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil {
- ws.Close()
- break
- }
- }
- if s.Err() != nil {
- log.Println("scan:", s.Err())
- }
- close(done)
-
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
- time.Sleep(closeGracePeriod)
- ws.Close()
-}
-
-func ping(ws *websocket.Conn, done chan struct{}) {
- ticker := time.NewTicker(pingPeriod)
- defer ticker.Stop()
- for {
- select {
- case <-ticker.C:
- if err := ws.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(writeWait)); err != nil {
- log.Println("ping:", err)
- }
- case <-done:
- return
- }
- }
-}
-
-func internalError(ws *websocket.Conn, msg string, err error) {
- log.Println(msg, err)
- ws.WriteMessage(websocket.TextMessage, []byte("Internal server error."))
-}
-
-var upgrader = websocket.Upgrader{}
-
-func serveWs(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Println("upgrade:", err)
- return
- }
-
- defer ws.Close()
-
- outr, outw, err := os.Pipe()
- if err != nil {
- internalError(ws, "stdout:", err)
- return
- }
- defer outr.Close()
- defer outw.Close()
-
- inr, inw, err := os.Pipe()
- if err != nil {
- internalError(ws, "stdin:", err)
- return
- }
- defer inr.Close()
- defer inw.Close()
-
- proc, err := os.StartProcess(cmdPath, flag.Args(), &os.ProcAttr{
- Files: []*os.File{inr, outw, outw},
- })
- if err != nil {
- internalError(ws, "start:", err)
- return
- }
-
- inr.Close()
- outw.Close()
-
- stdoutDone := make(chan struct{})
- go pumpStdout(ws, outr, stdoutDone)
- go ping(ws, stdoutDone)
-
- pumpStdin(ws, inw)
-
- // Some commands will exit when stdin is closed.
- inw.Close()
-
- // Other commands need a bonk on the head.
- if err := proc.Signal(os.Interrupt); err != nil {
- log.Println("inter:", err)
- }
-
- select {
- case <-stdoutDone:
- case <-time.After(time.Second):
- // A bigger bonk on the head.
- if err := proc.Signal(os.Kill); err != nil {
- log.Println("term:", err)
- }
- <-stdoutDone
- }
-
- if _, err := proc.Wait(); err != nil {
- log.Println("wait:", err)
- }
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- http.ServeFile(w, r, "home.html")
-}
-
-func main() {
- flag.Parse()
- if len(flag.Args()) < 1 {
- log.Fatal("must specify at least one argument")
- }
- var err error
- cmdPath, err = exec.LookPath(flag.Args()[0])
- if err != nil {
- log.Fatal(err)
- }
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", serveWs)
- log.Fatal(http.ListenAndServe(*addr, nil))
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/echo/README.md b/vendor/github.com/gorilla/websocket/examples/echo/README.md
deleted file mode 100644
index 6ad79ed76..000000000
--- a/vendor/github.com/gorilla/websocket/examples/echo/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Client and server example
-
-This example shows a simple client and server.
-
-The server echoes messages sent to it. The client sends a message every second
-and prints all messages received.
-
-To run the example, start the server:
-
- $ go run server.go
-
-Next, start the client:
-
- $ go run client.go
-
-The server includes a simple web client. To use the client, open
-http://127.0.0.1:8080 in the browser and follow the instructions on the page.
diff --git a/vendor/github.com/gorilla/websocket/examples/echo/client.go b/vendor/github.com/gorilla/websocket/examples/echo/client.go
deleted file mode 100644
index 6578094e7..000000000
--- a/vendor/github.com/gorilla/websocket/examples/echo/client.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "log"
- "net/url"
- "os"
- "os/signal"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-var addr = flag.String("addr", "localhost:8080", "http service address")
-
-func main() {
- flag.Parse()
- log.SetFlags(0)
-
- interrupt := make(chan os.Signal, 1)
- signal.Notify(interrupt, os.Interrupt)
-
- u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}
- log.Printf("connecting to %s", u.String())
-
- c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
- if err != nil {
- log.Fatal("dial:", err)
- }
- defer c.Close()
-
- done := make(chan struct{})
-
- go func() {
- defer c.Close()
- defer close(done)
- for {
- _, message, err := c.ReadMessage()
- if err != nil {
- log.Println("read:", err)
- return
- }
- log.Printf("recv: %s", message)
- }
- }()
-
- ticker := time.NewTicker(time.Second)
- defer ticker.Stop()
-
- for {
- select {
- case t := <-ticker.C:
- err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
- if err != nil {
- log.Println("write:", err)
- return
- }
- case <-interrupt:
- log.Println("interrupt")
- // To cleanly close a connection, a client should send a close
- // frame and wait for the server to close the connection.
- err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
- if err != nil {
- log.Println("write close:", err)
- return
- }
- select {
- case <-done:
- case <-time.After(time.Second):
- }
- c.Close()
- return
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/examples/echo/server.go b/vendor/github.com/gorilla/websocket/examples/echo/server.go
deleted file mode 100644
index ecc680c8b..000000000
--- a/vendor/github.com/gorilla/websocket/examples/echo/server.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "html/template"
- "log"
- "net/http"
-
- "github.com/gorilla/websocket"
-)
-
-var addr = flag.String("addr", "localhost:8080", "http service address")
-
-var upgrader = websocket.Upgrader{} // use default options
-
-func echo(w http.ResponseWriter, r *http.Request) {
- c, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- log.Print("upgrade:", err)
- return
- }
- defer c.Close()
- for {
- mt, message, err := c.ReadMessage()
- if err != nil {
- log.Println("read:", err)
- break
- }
- log.Printf("recv: %s", message)
- err = c.WriteMessage(mt, message)
- if err != nil {
- log.Println("write:", err)
- break
- }
- }
-}
-
-func home(w http.ResponseWriter, r *http.Request) {
- homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
-}
-
-func main() {
- flag.Parse()
- log.SetFlags(0)
- http.HandleFunc("/echo", echo)
- http.HandleFunc("/", home)
- log.Fatal(http.ListenAndServe(*addr, nil))
-}
-
-var homeTemplate = template.Must(template.New("").Parse(`
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<script>
-window.addEventListener("load", function(evt) {
-
- var output = document.getElementById("output");
- var input = document.getElementById("input");
- var ws;
-
- var print = function(message) {
- var d = document.createElement("div");
- d.innerHTML = message;
- output.appendChild(d);
- };
-
- document.getElementById("open").onclick = function(evt) {
- if (ws) {
- return false;
- }
- ws = new WebSocket("{{.}}");
- ws.onopen = function(evt) {
- print("OPEN");
- }
- ws.onclose = function(evt) {
- print("CLOSE");
- ws = null;
- }
- ws.onmessage = function(evt) {
- print("RESPONSE: " + evt.data);
- }
- ws.onerror = function(evt) {
- print("ERROR: " + evt.data);
- }
- return false;
- };
-
- document.getElementById("send").onclick = function(evt) {
- if (!ws) {
- return false;
- }
- print("SEND: " + input.value);
- ws.send(input.value);
- return false;
- };
-
- document.getElementById("close").onclick = function(evt) {
- if (!ws) {
- return false;
- }
- ws.close();
- return false;
- };
-
-});
-</script>
-</head>
-<body>
-<table>
-<tr><td valign="top" width="50%">
-<p>Click "Open" to create a connection to the server,
-"Send" to send a message to the server and "Close" to close the connection.
-You can change the message and send multiple times.
-<p>
-<form>
-<button id="open">Open</button>
-<button id="close">Close</button>
-<p><input id="input" type="text" value="Hello world!">
-<button id="send">Send</button>
-</form>
-</td><td valign="top" width="50%">
-<div id="output"></div>
-</td></tr></table>
-</body>
-</html>
-`))
diff --git a/vendor/github.com/gorilla/websocket/examples/filewatch/README.md b/vendor/github.com/gorilla/websocket/examples/filewatch/README.md
deleted file mode 100644
index ca4931f3b..000000000
--- a/vendor/github.com/gorilla/websocket/examples/filewatch/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# File Watch example.
-
-This example sends a file to the browser client for display whenever the file is modified.
-
- $ go get github.com/gorilla/websocket
- $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/filewatch`
- $ go run main.go <name of file to watch>
- # Open http://localhost:8080/ .
- # Modify the file to see it update in the browser.
diff --git a/vendor/github.com/gorilla/websocket/examples/filewatch/main.go b/vendor/github.com/gorilla/websocket/examples/filewatch/main.go
deleted file mode 100644
index f5f9da5c3..000000000
--- a/vendor/github.com/gorilla/websocket/examples/filewatch/main.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "flag"
- "html/template"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "strconv"
- "time"
-
- "github.com/gorilla/websocket"
-)
-
-const (
- // Time allowed to write the file to the client.
- writeWait = 10 * time.Second
-
- // Time allowed to read the next pong message from the client.
- pongWait = 60 * time.Second
-
- // Send pings to client with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Poll file for changes with this period.
- filePeriod = 10 * time.Second
-)
-
-var (
- addr = flag.String("addr", ":8080", "http service address")
- homeTempl = template.Must(template.New("").Parse(homeHTML))
- filename string
- upgrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- }
-)
-
-func readFileIfModified(lastMod time.Time) ([]byte, time.Time, error) {
- fi, err := os.Stat(filename)
- if err != nil {
- return nil, lastMod, err
- }
- if !fi.ModTime().After(lastMod) {
- return nil, lastMod, nil
- }
- p, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, fi.ModTime(), err
- }
- return p, fi.ModTime(), nil
-}
-
-func reader(ws *websocket.Conn) {
- defer ws.Close()
- ws.SetReadLimit(512)
- ws.SetReadDeadline(time.Now().Add(pongWait))
- ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
- for {
- _, _, err := ws.ReadMessage()
- if err != nil {
- break
- }
- }
-}
-
-func writer(ws *websocket.Conn, lastMod time.Time) {
- lastError := ""
- pingTicker := time.NewTicker(pingPeriod)
- fileTicker := time.NewTicker(filePeriod)
- defer func() {
- pingTicker.Stop()
- fileTicker.Stop()
- ws.Close()
- }()
- for {
- select {
- case <-fileTicker.C:
- var p []byte
- var err error
-
- p, lastMod, err = readFileIfModified(lastMod)
-
- if err != nil {
- if s := err.Error(); s != lastError {
- lastError = s
- p = []byte(lastError)
- }
- } else {
- lastError = ""
- }
-
- if p != nil {
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.TextMessage, p); err != nil {
- return
- }
- }
- case <-pingTicker.C:
- ws.SetWriteDeadline(time.Now().Add(writeWait))
- if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
- return
- }
- }
- }
-}
-
-func serveWs(w http.ResponseWriter, r *http.Request) {
- ws, err := upgrader.Upgrade(w, r, nil)
- if err != nil {
- if _, ok := err.(websocket.HandshakeError); !ok {
- log.Println(err)
- }
- return
- }
-
- var lastMod time.Time
- if n, err := strconv.ParseInt(r.FormValue("lastMod"), 16, 64); err == nil {
- lastMod = time.Unix(0, n)
- }
-
- go writer(ws, lastMod)
- reader(ws)
-}
-
-func serveHome(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path != "/" {
- http.Error(w, "Not found", 404)
- return
- }
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- p, lastMod, err := readFileIfModified(time.Time{})
- if err != nil {
- p = []byte(err.Error())
- lastMod = time.Unix(0, 0)
- }
- var v = struct {
- Host string
- Data string
- LastMod string
- }{
- r.Host,
- string(p),
- strconv.FormatInt(lastMod.UnixNano(), 16),
- }
- homeTempl.Execute(w, &v)
-}
-
-func main() {
- flag.Parse()
- if flag.NArg() != 1 {
- log.Fatal("filename not specified")
- }
- filename = flag.Args()[0]
- http.HandleFunc("/", serveHome)
- http.HandleFunc("/ws", serveWs)
- if err := http.ListenAndServe(*addr, nil); err != nil {
- log.Fatal(err)
- }
-}
-
-const homeHTML = `<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>WebSocket Example</title>
- </head>
- <body>
- <pre id="fileData">{{.Data}}</pre>
- <script type="text/javascript">
- (function() {
- var data = document.getElementById("fileData");
- var conn = new WebSocket("ws://{{.Host}}/ws?lastMod={{.LastMod}}");
- conn.onclose = function(evt) {
- data.textContent = 'Connection closed';
- }
- conn.onmessage = function(evt) {
- console.log('file updated');
- data.textContent = evt.data;
- }
- })();
- </script>
- </body>
-</html>
-`
diff --git a/vendor/github.com/gorilla/websocket/json_test.go b/vendor/github.com/gorilla/websocket/json_test.go
deleted file mode 100644
index 61100e481..000000000
--- a/vendor/github.com/gorilla/websocket/json_test.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "bytes"
- "encoding/json"
- "io"
- "reflect"
- "testing"
-)
-
-func TestJSON(t *testing.T) {
- var buf bytes.Buffer
- c := fakeNetConn{&buf, &buf}
- wc := newConn(c, true, 1024, 1024)
- rc := newConn(c, false, 1024, 1024)
-
- var actual, expect struct {
- A int
- B string
- }
- expect.A = 1
- expect.B = "hello"
-
- if err := wc.WriteJSON(&expect); err != nil {
- t.Fatal("write", err)
- }
-
- if err := rc.ReadJSON(&actual); err != nil {
- t.Fatal("read", err)
- }
-
- if !reflect.DeepEqual(&actual, &expect) {
- t.Fatal("equal", actual, expect)
- }
-}
-
-func TestPartialJSONRead(t *testing.T) {
- var buf bytes.Buffer
- c := fakeNetConn{&buf, &buf}
- wc := newConn(c, true, 1024, 1024)
- rc := newConn(c, false, 1024, 1024)
-
- var v struct {
- A int
- B string
- }
- v.A = 1
- v.B = "hello"
-
- messageCount := 0
-
- // Partial JSON values.
-
- data, err := json.Marshal(v)
- if err != nil {
- t.Fatal(err)
- }
- for i := len(data) - 1; i >= 0; i-- {
- if err := wc.WriteMessage(TextMessage, data[:i]); err != nil {
- t.Fatal(err)
- }
- messageCount++
- }
-
- // Whitespace.
-
- if err := wc.WriteMessage(TextMessage, []byte(" ")); err != nil {
- t.Fatal(err)
- }
- messageCount++
-
- // Close.
-
- if err := wc.WriteMessage(CloseMessage, FormatCloseMessage(CloseNormalClosure, "")); err != nil {
- t.Fatal(err)
- }
-
- for i := 0; i < messageCount; i++ {
- err := rc.ReadJSON(&v)
- if err != io.ErrUnexpectedEOF {
- t.Error("read", i, err)
- }
- }
-
- err = rc.ReadJSON(&v)
- if _, ok := err.(*CloseError); !ok {
- t.Error("final", err)
- }
-}
-
-func TestDeprecatedJSON(t *testing.T) {
- var buf bytes.Buffer
- c := fakeNetConn{&buf, &buf}
- wc := newConn(c, true, 1024, 1024)
- rc := newConn(c, false, 1024, 1024)
-
- var actual, expect struct {
- A int
- B string
- }
- expect.A = 1
- expect.B = "hello"
-
- if err := WriteJSON(wc, &expect); err != nil {
- t.Fatal("write", err)
- }
-
- if err := ReadJSON(rc, &actual); err != nil {
- t.Fatal("read", err)
- }
-
- if !reflect.DeepEqual(&actual, &expect) {
- t.Fatal("equal", actual, expect)
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/mask_test.go b/vendor/github.com/gorilla/websocket/mask_test.go
deleted file mode 100644
index 298a1e509..000000000
--- a/vendor/github.com/gorilla/websocket/mask_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
-// this source code is governed by a BSD-style license that can be found in the
-// LICENSE file.
-
-// Require 1.7 for sub-bencmarks
-// +build go1.7,!appengine
-
-package websocket
-
-import (
- "fmt"
- "testing"
-)
-
-func maskBytesByByte(key [4]byte, pos int, b []byte) int {
- for i := range b {
- b[i] ^= key[pos&3]
- pos++
- }
- return pos & 3
-}
-
-func notzero(b []byte) int {
- for i := range b {
- if b[i] != 0 {
- return i
- }
- }
- return -1
-}
-
-func TestMaskBytes(t *testing.T) {
- key := [4]byte{1, 2, 3, 4}
- for size := 1; size <= 1024; size++ {
- for align := 0; align < wordSize; align++ {
- for pos := 0; pos < 4; pos++ {
- b := make([]byte, size+align)[align:]
- maskBytes(key, pos, b)
- maskBytesByByte(key, pos, b)
- if i := notzero(b); i >= 0 {
- t.Errorf("size:%d, align:%d, pos:%d, offset:%d", size, align, pos, i)
- }
- }
- }
- }
-}
-
-func BenchmarkMaskBytes(b *testing.B) {
- for _, size := range []int{2, 4, 8, 16, 32, 512, 1024} {
- b.Run(fmt.Sprintf("size-%d", size), func(b *testing.B) {
- for _, align := range []int{wordSize / 2} {
- b.Run(fmt.Sprintf("align-%d", align), func(b *testing.B) {
- for _, fn := range []struct {
- name string
- fn func(key [4]byte, pos int, b []byte) int
- }{
- {"byte", maskBytesByByte},
- {"word", maskBytes},
- } {
- b.Run(fn.name, func(b *testing.B) {
- key := newMaskKey()
- data := make([]byte, size+align)[align:]
- for i := 0; i < b.N; i++ {
- fn.fn(key, 0, data)
- }
- b.SetBytes(int64(len(data)))
- })
- }
- })
- }
- })
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/prepared_test.go b/vendor/github.com/gorilla/websocket/prepared_test.go
deleted file mode 100644
index cf98c6c10..000000000
--- a/vendor/github.com/gorilla/websocket/prepared_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "bytes"
- "compress/flate"
- "math/rand"
- "testing"
-)
-
-var preparedMessageTests = []struct {
- messageType int
- isServer bool
- enableWriteCompression bool
- compressionLevel int
-}{
- // Server
- {TextMessage, true, false, flate.BestSpeed},
- {TextMessage, true, true, flate.BestSpeed},
- {TextMessage, true, true, flate.BestCompression},
- {PingMessage, true, false, flate.BestSpeed},
- {PingMessage, true, true, flate.BestSpeed},
-
- // Client
- {TextMessage, false, false, flate.BestSpeed},
- {TextMessage, false, true, flate.BestSpeed},
- {TextMessage, false, true, flate.BestCompression},
- {PingMessage, false, false, flate.BestSpeed},
- {PingMessage, false, true, flate.BestSpeed},
-}
-
-func TestPreparedMessage(t *testing.T) {
- for _, tt := range preparedMessageTests {
- var data = []byte("this is a test")
- var buf bytes.Buffer
- c := newConn(fakeNetConn{Reader: nil, Writer: &buf}, tt.isServer, 1024, 1024)
- if tt.enableWriteCompression {
- c.newCompressionWriter = compressNoContextTakeover
- }
- c.SetCompressionLevel(tt.compressionLevel)
-
- // Seed random number generator for consistent frame mask.
- rand.Seed(1234)
-
- if err := c.WriteMessage(tt.messageType, data); err != nil {
- t.Fatal(err)
- }
- want := buf.String()
-
- pm, err := NewPreparedMessage(tt.messageType, data)
- if err != nil {
- t.Fatal(err)
- }
-
- // Scribble on data to ensure that NewPreparedMessage takes a snapshot.
- copy(data, "hello world")
-
- // Seed random number generator for consistent frame mask.
- rand.Seed(1234)
-
- buf.Reset()
- if err := c.WritePreparedMessage(pm); err != nil {
- t.Fatal(err)
- }
- got := buf.String()
-
- if got != want {
- t.Errorf("write message != prepared message for %+v", tt)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go
index 50b58a893..3e96a00c8 100644
--- a/vendor/github.com/gorilla/websocket/server.go
+++ b/vendor/github.com/gorilla/websocket/server.go
@@ -243,7 +243,7 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
// of the same origin policy check is:
//
// if req.Header.Get("Origin") != "http://"+req.Host {
-// http.Error(w, "Origin not allowed", 403)
+// http.Error(w, "Origin not allowed", http.StatusForbidden)
// return
// }
//
diff --git a/vendor/github.com/gorilla/websocket/server_test.go b/vendor/github.com/gorilla/websocket/server_test.go
deleted file mode 100644
index c43dbb267..000000000
--- a/vendor/github.com/gorilla/websocket/server_test.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "net/http"
- "reflect"
- "testing"
-)
-
-var subprotocolTests = []struct {
- h string
- protocols []string
-}{
- {"", nil},
- {"foo", []string{"foo"}},
- {"foo,bar", []string{"foo", "bar"}},
- {"foo, bar", []string{"foo", "bar"}},
- {" foo, bar", []string{"foo", "bar"}},
- {" foo, bar ", []string{"foo", "bar"}},
-}
-
-func TestSubprotocols(t *testing.T) {
- for _, st := range subprotocolTests {
- r := http.Request{Header: http.Header{"Sec-Websocket-Protocol": {st.h}}}
- protocols := Subprotocols(&r)
- if !reflect.DeepEqual(st.protocols, protocols) {
- t.Errorf("SubProtocols(%q) returned %#v, want %#v", st.h, protocols, st.protocols)
- }
- }
-}
-
-var isWebSocketUpgradeTests = []struct {
- ok bool
- h http.Header
-}{
- {false, http.Header{"Upgrade": {"websocket"}}},
- {false, http.Header{"Connection": {"upgrade"}}},
- {true, http.Header{"Connection": {"upgRade"}, "Upgrade": {"WebSocket"}}},
-}
-
-func TestIsWebSocketUpgrade(t *testing.T) {
- for _, tt := range isWebSocketUpgradeTests {
- ok := IsWebSocketUpgrade(&http.Request{Header: tt.h})
- if tt.ok != ok {
- t.Errorf("IsWebSocketUpgrade(%v) returned %v, want %v", tt.h, ok, tt.ok)
- }
- }
-}
-
-var checkSameOriginTests = []struct {
- ok bool
- r *http.Request
-}{
- {false, &http.Request{Host: "example.org", Header: map[string][]string{"Origin": []string{"https://other.org"}}}},
- {true, &http.Request{Host: "example.org", Header: map[string][]string{"Origin": []string{"https://example.org"}}}},
- {true, &http.Request{Host: "Example.org", Header: map[string][]string{"Origin": []string{"https://example.org"}}}},
-}
-
-func TestCheckSameOrigin(t *testing.T) {
- for _, tt := range checkSameOriginTests {
- ok := checkSameOrigin(tt.r)
- if tt.ok != ok {
- t.Errorf("checkSameOrigin(%+v) returned %v, want %v", tt.r, ok, tt.ok)
- }
- }
-}
diff --git a/vendor/github.com/gorilla/websocket/util_test.go b/vendor/github.com/gorilla/websocket/util_test.go
deleted file mode 100644
index 6e15965f5..000000000
--- a/vendor/github.com/gorilla/websocket/util_test.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
- "net/http"
- "reflect"
- "testing"
-)
-
-var equalASCIIFoldTests = []struct {
- t, s string
- eq bool
-}{
- {"WebSocket", "websocket", true},
- {"websocket", "WebSocket", true},
- {"Öyster", "öyster", false},
-}
-
-func TestEqualASCIIFold(t *testing.T) {
- for _, tt := range equalASCIIFoldTests {
- eq := equalASCIIFold(tt.s, tt.t)
- if eq != tt.eq {
- t.Errorf("equalASCIIFold(%q, %q) = %v, want %v", tt.s, tt.t, eq, tt.eq)
- }
- }
-}
-
-var tokenListContainsValueTests = []struct {
- value string
- ok bool
-}{
- {"WebSocket", true},
- {"WEBSOCKET", true},
- {"websocket", true},
- {"websockets", false},
- {"x websocket", false},
- {"websocket x", false},
- {"other,websocket,more", true},
- {"other, websocket, more", true},
-}
-
-func TestTokenListContainsValue(t *testing.T) {
- for _, tt := range tokenListContainsValueTests {
- h := http.Header{"Upgrade": {tt.value}}
- ok := tokenListContainsValue(h, "Upgrade", "websocket")
- if ok != tt.ok {
- t.Errorf("tokenListContainsValue(h, n, %q) = %v, want %v", tt.value, ok, tt.ok)
- }
- }
-}
-
-var parseExtensionTests = []struct {
- value string
- extensions []map[string]string
-}{
- {`foo`, []map[string]string{{"": "foo"}}},
- {`foo, bar; baz=2`, []map[string]string{
- {"": "foo"},
- {"": "bar", "baz": "2"}}},
- {`foo; bar="b,a;z"`, []map[string]string{
- {"": "foo", "bar": "b,a;z"}}},
- {`foo , bar; baz = 2`, []map[string]string{
- {"": "foo"},
- {"": "bar", "baz": "2"}}},
- {`foo, bar; baz=2 junk`, []map[string]string{
- {"": "foo"}}},
- {`foo junk, bar; baz=2 junk`, nil},
- {`mux; max-channels=4; flow-control, deflate-stream`, []map[string]string{
- {"": "mux", "max-channels": "4", "flow-control": ""},
- {"": "deflate-stream"}}},
- {`permessage-foo; x="10"`, []map[string]string{
- {"": "permessage-foo", "x": "10"}}},
- {`permessage-foo; use_y, permessage-foo`, []map[string]string{
- {"": "permessage-foo", "use_y": ""},
- {"": "permessage-foo"}}},
- {`permessage-deflate; client_max_window_bits; server_max_window_bits=10 , permessage-deflate; client_max_window_bits`, []map[string]string{
- {"": "permessage-deflate", "client_max_window_bits": "", "server_max_window_bits": "10"},
- {"": "permessage-deflate", "client_max_window_bits": ""}}},
- {"permessage-deflate; server_no_context_takeover; client_max_window_bits=15", []map[string]string{
- {"": "permessage-deflate", "server_no_context_takeover": "", "client_max_window_bits": "15"},
- }},
-}
-
-func TestParseExtensions(t *testing.T) {
- for _, tt := range parseExtensionTests {
- h := http.Header{http.CanonicalHeaderKey("Sec-WebSocket-Extensions"): {tt.value}}
- extensions := parseExtensions(h)
- if !reflect.DeepEqual(extensions, tt.extensions) {
- t.Errorf("parseExtensions(%q)\n = %v,\nwant %v", tt.value, extensions, tt.extensions)
- }
- }
-}