diff --git a/glide.lock b/glide.lock index c980a991..514be3e5 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 4826a83c4ef4490fd09c560e6a8c8737a7586a97f1beb72294123db65be5ac38 -updated: 2018-04-23T02:10:12.581595+08:00 +hash: 367ad1f2515b51db9d04d5620fd88843fb6faabf303fe3103b896ef7a3f5a126 +updated: 2018-04-23T02:30:29.768749+08:00 imports: - name: github.com/armon/go-socks5 version: e75332964ef517daa070d7c38a9466a0d687e0a5 @@ -16,7 +16,7 @@ imports: - name: github.com/golang/snappy version: 5979233c5d6225d4a8e438cdd0b411888449ddab - name: github.com/gorilla/websocket - version: 292fd08b2560ad524ee37396253d71570339a821 + version: ea4d1f681babbce9545c9c5f3d5194a789c89f5b - name: github.com/julienschmidt/httprouter version: 8a45e95fc75cb77048068a62daed98cc22fdac7c - name: github.com/klauspost/cpuid @@ -51,8 +51,6 @@ imports: - sm4 - name: github.com/vaughan0/go-ini version: a98ad7ee00ec53921f08832bc06ecf7fd600e6a1 -- name: github.com/xtaci/kcp-go - version: df437e2b8ec365a336200f9d9da53441cf72ed47 - name: github.com/xtaci/smux version: 2de5471dfcbc029f5fe1392b83fe784127c4943e - name: golang.org/x/crypto diff --git a/glide.yaml b/glide.yaml index 0e3ffdb7..2cc15352 100644 --- a/glide.yaml +++ b/glide.yaml @@ -46,8 +46,6 @@ import: - sm4 - package: github.com/vaughan0/go-ini version: a98ad7ee00ec53921f08832bc06ecf7fd600e6a1 -- package: github.com/xtaci/kcp-go - version: v3.17 - package: github.com/xtaci/smux version: 2de5471dfcbc029f5fe1392b83fe784127c4943e - package: golang.org/x/crypto @@ -72,3 +70,4 @@ import: - package: github.com/rodaine/table version: v1.0.0 - package: github.com/gorilla/websocket + version: v1.2.0 diff --git a/utils/net/conn.go b/utils/net/conn.go index b1877331..2c60ce2f 100644 --- a/utils/net/conn.go +++ b/utils/net/conn.go @@ -26,7 +26,7 @@ import ( "github.com/fatedier/frp/utils/log" - kcp "github.com/xtaci/kcp-go" + kcp "github.com/fatedier/kcp-go" ) // Conn is the interface of connections used in frp. diff --git a/vendor/github.com/gorilla/websocket/.travis.yml b/vendor/github.com/gorilla/websocket/.travis.yml index 9f233f98..3d8d29cf 100644 --- a/vendor/github.com/gorilla/websocket/.travis.yml +++ b/vendor/github.com/gorilla/websocket/.travis.yml @@ -8,7 +8,6 @@ matrix: - go: 1.6 - go: 1.7 - go: 1.8 - - go: 1.9 - go: tip allow_failures: - go: tip diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go index 934e28e9..43a87c75 100644 --- a/vendor/github.com/gorilla/websocket/client.go +++ b/vendor/github.com/gorilla/websocket/client.go @@ -5,8 +5,10 @@ package websocket import ( + "bufio" "bytes" "crypto/tls" + "encoding/base64" "errors" "io" "io/ioutil" @@ -86,6 +88,50 @@ type Dialer struct { var errMalformedURL = errors.New("malformed ws or wss URL") +// parseURL parses the URL. +// +// This function is a replacement for the standard library url.Parse function. +// In Go 1.4 and earlier, url.Parse loses information from the path. +func parseURL(s string) (*url.URL, error) { + // From the RFC: + // + // ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ] + // wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ] + var u url.URL + switch { + case strings.HasPrefix(s, "ws://"): + u.Scheme = "ws" + s = s[len("ws://"):] + case strings.HasPrefix(s, "wss://"): + u.Scheme = "wss" + s = s[len("wss://"):] + default: + return nil, errMalformedURL + } + + if i := strings.Index(s, "?"); i >= 0 { + u.RawQuery = s[i+1:] + s = s[:i] + } + + if i := strings.Index(s, "/"); i >= 0 { + u.Opaque = s[i:] + s = s[:i] + } else { + u.Opaque = "/" + } + + u.Host = s + + if strings.Contains(u.Host, "@") { + // Don't bother parsing user information because user information is + // not allowed in websocket URIs. + return nil, errMalformedURL + } + + return &u, nil +} + func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { hostPort = u.Host hostNoPort = u.Host @@ -104,7 +150,7 @@ func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { return hostPort, hostNoPort } -// DefaultDialer is a dialer with all fields set to the default values. +// DefaultDialer is a dialer with all fields set to the default zero values. var DefaultDialer = &Dialer{ Proxy: http.ProxyFromEnvironment, } @@ -131,7 +177,7 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re return nil, nil, err } - u, err := url.Parse(urlStr) + u, err := parseURL(urlStr) if err != nil { return nil, nil, err } @@ -200,52 +246,36 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re req.Header.Set("Sec-Websocket-Extensions", "permessage-deflate; server_no_context_takeover; client_no_context_takeover") } + hostPort, hostNoPort := hostPortNoPort(u) + + var proxyURL *url.URL + // Check wether the proxy method has been configured + if d.Proxy != nil { + proxyURL, err = d.Proxy(req) + } + if err != nil { + return nil, nil, err + } + + var targetHostPort string + if proxyURL != nil { + targetHostPort, _ = hostPortNoPort(proxyURL) + } else { + targetHostPort = hostPort + } + var deadline time.Time if d.HandshakeTimeout != 0 { deadline = time.Now().Add(d.HandshakeTimeout) } - // Get network dial function. netDial := d.NetDial if netDial == nil { netDialer := &net.Dialer{Deadline: deadline} netDial = netDialer.Dial } - // If needed, wrap the dial function to set the connection deadline. - if !deadline.Equal(time.Time{}) { - forwardDial := netDial - netDial = func(network, addr string) (net.Conn, error) { - c, err := forwardDial(network, addr) - if err != nil { - return nil, err - } - err = c.SetDeadline(deadline) - if err != nil { - c.Close() - return nil, err - } - return c, nil - } - } - - // If needed, wrap the dial function to connect through a proxy. - if d.Proxy != nil { - proxyURL, err := d.Proxy(req) - if err != nil { - return nil, nil, err - } - if proxyURL != nil { - dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial)) - if err != nil { - return nil, nil, err - } - netDial = dialer.Dial - } - } - - hostPort, hostNoPort := hostPortNoPort(u) - netConn, err := netDial("tcp", hostPort) + netConn, err := netDial("tcp", targetHostPort) if err != nil { return nil, nil, err } @@ -256,6 +286,42 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re } }() + if err := netConn.SetDeadline(deadline); err != nil { + return nil, nil, err + } + + if proxyURL != nil { + connectHeader := make(http.Header) + if user := proxyURL.User; user != nil { + proxyUser := user.Username() + if proxyPassword, passwordSet := user.Password(); passwordSet { + credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) + connectHeader.Set("Proxy-Authorization", "Basic "+credential) + } + } + connectReq := &http.Request{ + Method: "CONNECT", + URL: &url.URL{Opaque: hostPort}, + Host: hostPort, + Header: connectHeader, + } + + connectReq.Write(netConn) + + // Read response. + // Okay to use and discard buffered reader here, because + // TLS server will not speak until spoken to. + br := bufio.NewReader(netConn) + resp, err := http.ReadResponse(br, connectReq) + if err != nil { + return nil, nil, err + } + if resp.StatusCode != 200 { + f := strings.SplitN(resp.Status, " ", 2) + return nil, nil, errors.New(f[1]) + } + } + if u.Scheme == "https" { cfg := cloneTLSConfig(d.TLSClientConfig) if cfg.ServerName == "" { diff --git a/vendor/github.com/gorilla/websocket/client_server_test.go b/vendor/github.com/gorilla/websocket/client_server_test.go index 50063b7e..7d39da68 100644 --- a/vendor/github.com/gorilla/websocket/client_server_test.go +++ b/vendor/github.com/gorilla/websocket/client_server_test.go @@ -5,14 +5,11 @@ package websocket import ( - "bytes" "crypto/tls" "crypto/x509" "encoding/base64" - "encoding/binary" "io" "io/ioutil" - "net" "net/http" "net/http/cookiejar" "net/http/httptest" @@ -34,10 +31,9 @@ var cstUpgrader = Upgrader{ } var cstDialer = Dialer{ - Subprotocols: []string{"p1", "p2"}, - ReadBufferSize: 1024, - WriteBufferSize: 1024, - HandshakeTimeout: 30 * time.Second, + Subprotocols: []string{"p1", "p2"}, + ReadBufferSize: 1024, + WriteBufferSize: 1024, } type cstHandler struct{ *testing.T } @@ -147,9 +143,8 @@ func TestProxyDial(t *testing.T) { s := newServer(t) defer s.Close() - surl, _ := url.Parse(s.Server.URL) + surl, _ := url.Parse(s.URL) - cstDialer := cstDialer // make local copy for modification on next line. cstDialer.Proxy = http.ProxyURL(surl) connect := false @@ -165,8 +160,8 @@ func TestProxyDial(t *testing.T) { } if !connect { - t.Log("connect not received") - http.Error(w, "connect not received", 405) + t.Log("connect not recieved") + http.Error(w, "connect not recieved", 405) return } origHandler.ServeHTTP(w, r) @@ -178,16 +173,16 @@ func TestProxyDial(t *testing.T) { } defer ws.Close() sendRecv(t, ws) + + cstDialer.Proxy = http.ProxyFromEnvironment } func TestProxyAuthorizationDial(t *testing.T) { s := newServer(t) defer s.Close() - surl, _ := url.Parse(s.Server.URL) + surl, _ := url.Parse(s.URL) surl.User = url.UserPassword("username", "password") - - cstDialer := cstDialer // make local copy for modification on next line. cstDialer.Proxy = http.ProxyURL(surl) connect := false @@ -205,8 +200,8 @@ func TestProxyAuthorizationDial(t *testing.T) { } if !connect { - t.Log("connect with proxy authorization not received") - http.Error(w, "connect with proxy authorization not received", 405) + t.Log("connect with proxy authorization not recieved") + http.Error(w, "connect with proxy authorization not recieved", 405) return } origHandler.ServeHTTP(w, r) @@ -218,6 +213,8 @@ func TestProxyAuthorizationDial(t *testing.T) { } defer ws.Close() sendRecv(t, ws) + + cstDialer.Proxy = http.ProxyFromEnvironment } func TestDial(t *testing.T) { @@ -240,7 +237,7 @@ func TestDialCookieJar(t *testing.T) { d := cstDialer d.Jar = jar - u, _ := url.Parse(s.URL) + u, _ := parseURL(s.URL) switch u.Scheme { case "ws": @@ -249,7 +246,7 @@ func TestDialCookieJar(t *testing.T) { u.Scheme = "https" } - cookies := []*http.Cookie{{Name: "gorilla", Value: "ws", Path: "/"}} + cookies := []*http.Cookie{&http.Cookie{Name: "gorilla", Value: "ws", Path: "/"}} d.Jar.SetCookies(u, cookies) ws, _, err := d.Dial(s.URL, nil) @@ -401,17 +398,9 @@ func TestBadMethod(t *testing.T) { })) defer s.Close() - req, err := http.NewRequest("POST", s.URL, strings.NewReader("")) + resp, err := http.PostForm(s.URL, url.Values{}) 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) + t.Fatalf("PostForm returned error %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusMethodNotAllowed { @@ -521,82 +510,3 @@ func TestDialCompression(t *testing.T) { 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 index 5aa27b37..7d2b0844 100644 --- a/vendor/github.com/gorilla/websocket/client_test.go +++ b/vendor/github.com/gorilla/websocket/client_test.go @@ -6,9 +6,49 @@ package websocket import ( "net/url" + "reflect" "testing" ) +var parseURLTests = []struct { + s string + u *url.URL + rui string +}{ + {"ws://example.com/", &url.URL{Scheme: "ws", Host: "example.com", Opaque: "/"}, "/"}, + {"ws://example.com", &url.URL{Scheme: "ws", Host: "example.com", Opaque: "/"}, "/"}, + {"ws://example.com:7777/", &url.URL{Scheme: "ws", Host: "example.com:7777", Opaque: "/"}, "/"}, + {"wss://example.com/", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/"}, "/"}, + {"wss://example.com/a/b", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/a/b"}, "/a/b"}, + {"ss://example.com/a/b", nil, ""}, + {"ws://webmaster@example.com/", nil, ""}, + {"wss://example.com/a/b?x=y", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/a/b", RawQuery: "x=y"}, "/a/b?x=y"}, + {"wss://example.com?x=y", &url.URL{Scheme: "wss", Host: "example.com", Opaque: "/", RawQuery: "x=y"}, "/?x=y"}, +} + +func TestParseURL(t *testing.T) { + for _, tt := range parseURLTests { + u, err := parseURL(tt.s) + if tt.u != nil && err != nil { + t.Errorf("parseURL(%q) returned error %v", tt.s, err) + continue + } + if tt.u == nil { + if err == nil { + t.Errorf("parseURL(%q) did not return error", tt.s) + } + continue + } + if !reflect.DeepEqual(u, tt.u) { + t.Errorf("parseURL(%q) = %v, want %v", tt.s, u, tt.u) + continue + } + if u.RequestURI() != tt.rui { + t.Errorf("parseURL(%q).RequestURI() = %v, want %v", tt.s, u.RequestURI(), tt.rui) + } + } +} + var hostPortNoPortTests = []struct { u *url.URL hostPort, hostNoPort string diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go index cd3569d5..97e1dbac 100644 --- a/vendor/github.com/gorilla/websocket/conn.go +++ b/vendor/github.com/gorilla/websocket/conn.go @@ -76,7 +76,7 @@ const ( // is UTF-8 encoded text. PingMessage = 9 - // PongMessage denotes a pong control message. The optional message payload + // PongMessage denotes a ping control message. The optional message payload // is UTF-8 encoded text. PongMessage = 10 ) @@ -100,8 +100,9 @@ func (e *netError) Error() string { return e.msg } func (e *netError) Temporary() bool { return e.temporary } func (e *netError) Timeout() bool { return e.timeout } -// CloseError represents a close message. +// CloseError represents close frame. type CloseError struct { + // Code is defined in RFC 6455, section 11.7. Code int @@ -342,8 +343,7 @@ func (c *Conn) Subprotocol() string { return c.subprotocol } -// Close closes the underlying network connection without sending or waiting -// for a close message. +// Close closes the underlying network connection without sending or waiting for a close frame. func (c *Conn) Close() error { return c.conn.Close() } @@ -484,9 +484,6 @@ func (c *Conn) prepWrite(messageType int) error { // // There can be at most one open writer on a connection. NextWriter closes the // previous writer if the application has not already done so. -// -// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and -// PongMessage) are supported. func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { if err := c.prepWrite(messageType); err != nil { return nil, err @@ -767,6 +764,7 @@ func (c *Conn) SetWriteDeadline(t time.Time) error { // Read methods func (c *Conn) advanceFrame() (int, error) { + // 1. Skip remainder of previous frame. if c.readRemaining > 0 { @@ -1035,7 +1033,7 @@ func (c *Conn) SetReadDeadline(t time.Time) error { } // SetReadLimit sets the maximum size for a message read from the peer. If a -// message exceeds the limit, the connection sends a close message to the peer +// message exceeds the limit, the connection sends a close frame to the peer // and returns ErrReadLimit to the application. func (c *Conn) SetReadLimit(limit int64) { c.readLimit = limit @@ -1048,21 +1046,24 @@ func (c *Conn) CloseHandler() func(code int, text string) error { // SetCloseHandler sets the handler for close messages received from the peer. // The code argument to h is the received close code or CloseNoStatusReceived -// if the close message is empty. The default close handler sends a close -// message back to the peer. +// if the close message is empty. The default close handler sends a close frame +// back to the peer. // // The application must read the connection to process close messages as -// described in the section on Control Messages above. +// described in the section on Control Frames above. // -// The connection read methods return a CloseError when a close message is +// The connection read methods return a CloseError when a close frame is // received. Most applications should handle close messages as part of their // normal error handling. Applications should only set a close handler when the -// application must perform some action before sending a close message back to +// application must perform some action before sending a close frame back to // the peer. func (c *Conn) SetCloseHandler(h func(code int, text string) error) { if h == nil { h = func(code int, text string) error { - message := FormatCloseMessage(code, "") + message := []byte{} + if code != CloseNoStatusReceived { + message = FormatCloseMessage(code, "") + } c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) return nil } @@ -1076,11 +1077,11 @@ func (c *Conn) PingHandler() func(appData string) error { } // SetPingHandler sets the handler for ping messages received from the peer. -// The appData argument to h is the PING message application data. The default +// The appData argument to h is the PING frame application data. The default // ping handler sends a pong to the peer. // // The application must read the connection to process ping messages as -// described in the section on Control Messages above. +// described in the section on Control Frames above. func (c *Conn) SetPingHandler(h func(appData string) error) { if h == nil { h = func(message string) error { @@ -1102,11 +1103,11 @@ func (c *Conn) PongHandler() func(appData string) error { } // SetPongHandler sets the handler for pong messages received from the peer. -// The appData argument to h is the PONG message application data. The default +// The appData argument to h is the PONG frame application data. The default // pong handler does nothing. // // The application must read the connection to process ping messages as -// described in the section on Control Messages above. +// described in the section on Control Frames above. func (c *Conn) SetPongHandler(h func(appData string) error) { if h == nil { h = func(string) error { return nil } @@ -1140,14 +1141,7 @@ func (c *Conn) SetCompressionLevel(level int) error { } // FormatCloseMessage formats closeCode and text as a WebSocket close message. -// An empty message is returned for code CloseNoStatusReceived. func FormatCloseMessage(closeCode int, text string) []byte { - if closeCode == CloseNoStatusReceived { - // Return empty message because it's illegal to send - // CloseNoStatusReceived. Return non-nil value in case application - // checks for nil. - return []byte{} - } buf := make([]byte, 2+len(text)) binary.BigEndian.PutUint16(buf, uint16(closeCode)) copy(buf[2:], text) diff --git a/vendor/github.com/gorilla/websocket/conn_test.go b/vendor/github.com/gorilla/websocket/conn_test.go index 5fda7b5c..06e9bc3f 100644 --- a/vendor/github.com/gorilla/websocket/conn_test.go +++ b/vendor/github.com/gorilla/websocket/conn_test.go @@ -341,6 +341,7 @@ func TestUnderlyingConn(t *testing.T) { } func TestBufioReadBytes(t *testing.T) { + // Test calling bufio.ReadBytes for value longer than read buffer size. m := make([]byte, 512) @@ -365,7 +366,7 @@ func TestBufioReadBytes(t *testing.T) { t.Fatalf("ReadBytes() returned %v", err) } if len(p) != len(m) { - t.Fatalf("read returned %d bytes, want %d bytes", len(p), len(m)) + t.Fatalf("read returnd %d bytes, want %d bytes", len(p), len(m)) } } diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go index 7cc885e2..e291a952 100644 --- a/vendor/github.com/gorilla/websocket/doc.go +++ b/vendor/github.com/gorilla/websocket/doc.go @@ -6,8 +6,9 @@ // // Overview // -// The Conn type represents a WebSocket connection. A server application calls -// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn: +// The Conn type represents a WebSocket connection. A server application uses +// the Upgrade function from an Upgrader object with a HTTP request handler +// to get a pointer to a Conn: // // var upgrader = websocket.Upgrader{ // ReadBufferSize: 1024, @@ -30,12 +31,10 @@ // for { // messageType, p, err := conn.ReadMessage() // if err != nil { -// log.Println(err) // return // } -// if err := conn.WriteMessage(messageType, p); err != nil { -// log.Println(err) -// return +// if err = conn.WriteMessage(messageType, p); err != nil { +// return err // } // } // @@ -86,26 +85,20 @@ // and pong. Call the connection WriteControl, WriteMessage or NextWriter // methods to send a control message to the peer. // -// Connections handle received close messages by calling the handler function -// set with the SetCloseHandler method and by returning a *CloseError from the -// NextReader, ReadMessage or the message Read method. The default close -// handler sends a close message to the peer. +// Connections handle received close messages by sending a close message to the +// peer and returning a *CloseError from the the NextReader, ReadMessage or the +// message Read method. // -// Connections handle received ping messages by calling the handler function -// set with the SetPingHandler method. The default ping handler sends a pong -// message to the peer. +// Connections handle received ping and pong messages by invoking callback +// functions set with SetPingHandler and SetPongHandler methods. The callback +// functions are called from the NextReader, ReadMessage and the message Read +// methods. // -// Connections handle received pong messages by calling the handler function -// set with the SetPongHandler method. The default pong handler does nothing. -// If an application sends ping messages, then the application should set a -// pong handler to receive the corresponding pong. +// The default ping handler sends a pong to the peer. The application's reading +// goroutine can block for a short time while the handler writes the pong data +// to the connection. // -// The control message handler functions are called from the NextReader, -// ReadMessage and message reader Read methods. The default close and ping -// handlers can block these methods for a short time when the handler writes to -// the connection. -// -// The application must read the connection to process close, ping and pong +// The application must read the connection to process ping, pong and close // messages sent from the peer. If the application is not otherwise interested // in messages from the peer, then the application should start a goroutine to // read and discard messages from the peer. A simple example is: @@ -154,9 +147,9 @@ // CheckOrigin: func(r *http.Request) bool { return true }, // } // -// The deprecated package-level Upgrade function does not perform origin -// checking. The application is responsible for checking the Origin header -// before calling the Upgrade function. +// The deprecated Upgrade function does not enforce an origin policy. It's the +// application's responsibility to check the Origin header before calling +// Upgrade. // // Compression EXPERIMENTAL // diff --git a/vendor/github.com/gorilla/websocket/examples/chat/README.md b/vendor/github.com/gorilla/websocket/examples/chat/README.md index 7baf3e32..47c82f90 100644 --- a/vendor/github.com/gorilla/websocket/examples/chat/README.md +++ b/vendor/github.com/gorilla/websocket/examples/chat/README.md @@ -1,6 +1,6 @@ # Chat Example -This application shows how to use the +This application shows how to use use the [websocket](https://github.com/gorilla/websocket) package to implement a simple web chat application. diff --git a/vendor/github.com/gorilla/websocket/examples/chat/client.go b/vendor/github.com/gorilla/websocket/examples/chat/client.go index 9461c1ea..ecfd9a7a 100644 --- a/vendor/github.com/gorilla/websocket/examples/chat/client.go +++ b/vendor/github.com/gorilla/websocket/examples/chat/client.go @@ -64,7 +64,7 @@ func (c *Client) readPump() { for { _, message, err := c.conn.ReadMessage() if err != nil { - if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { + if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) { log.Printf("error: %v", err) } break @@ -113,7 +113,7 @@ func (c *Client) writePump() { } case <-ticker.C: c.conn.SetWriteDeadline(time.Now().Add(writeWait)) - if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil { + if err := c.conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } diff --git a/vendor/github.com/gorilla/websocket/examples/echo/server.go b/vendor/github.com/gorilla/websocket/examples/echo/server.go index ecc680c8..a685b097 100644 --- a/vendor/github.com/gorilla/websocket/examples/echo/server.go +++ b/vendor/github.com/gorilla/websocket/examples/echo/server.go @@ -55,7 +55,6 @@ func main() { var homeTemplate = template.Must(template.New("").Parse(` -