summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/gorilla/websocket
diff options
context:
space:
mode:
author=Corey Hulen <corey@hulen.com>2015-11-23 15:53:48 -0800
committer=Corey Hulen <corey@hulen.com>2015-11-23 15:53:48 -0800
commit4f4cd5e63573da4d6edcc7d4213afaca67c19f88 (patch)
treecefbc7af53629d97644ca2f6b2369e9d879f0101 /Godeps/_workspace/src/github.com/gorilla/websocket
parentf8a3c9a14edca6df0647d89cf225f2470cbe025c (diff)
downloadchat-4f4cd5e63573da4d6edcc7d4213afaca67c19f88.tar.gz
chat-4f4cd5e63573da4d6edcc7d4213afaca67c19f88.tar.bz2
chat-4f4cd5e63573da4d6edcc7d4213afaca67c19f88.zip
upgrading libs
Diffstat (limited to 'Godeps/_workspace/src/github.com/gorilla/websocket')
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/README.md2
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/client.go246
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go93
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go1
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/conn.go48
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go44
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/doc.go13
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go2
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md1
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go8
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md19
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html96
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go188
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md17
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go55
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go132
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go2
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/json.go4
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go4
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/server.go3
20 files changed, 834 insertions, 144 deletions
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/README.md
index 9ad75a0f5..9d71959ea 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/README.md
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/README.md
@@ -7,6 +7,8 @@ Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
* [API Reference](http://godoc.org/github.com/gorilla/websocket)
* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
+* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
+* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
### Status
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/client.go b/Godeps/_workspace/src/github.com/gorilla/websocket/client.go
index 5bc27e193..3bf9b2e84 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/client.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/client.go
@@ -5,6 +5,7 @@
package websocket
import (
+ "bufio"
"bytes"
"crypto/tls"
"errors"
@@ -30,50 +31,17 @@ var ErrBadHandshake = errors.New("websocket: bad handshake")
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
// non-nil *http.Response so that callers can handle redirects, authentication,
// etc.
+//
+// Deprecated: Use Dialer instead.
func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
- challengeKey, err := generateChallengeKey()
- if err != nil {
- return nil, nil, err
+ d := Dialer{
+ ReadBufferSize: readBufSize,
+ WriteBufferSize: writeBufSize,
+ NetDial: func(net, addr string) (net.Conn, error) {
+ return netConn, nil
+ },
}
- acceptKey := computeAcceptKey(challengeKey)
-
- c = newConn(netConn, false, readBufSize, writeBufSize)
- p := c.writeBuf[:0]
- p = append(p, "GET "...)
- p = append(p, u.RequestURI()...)
- p = append(p, " HTTP/1.1\r\nHost: "...)
- p = append(p, u.Host...)
- // "Upgrade" is capitalized for servers that do not use case insensitive
- // comparisons on header tokens.
- p = append(p, "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: "...)
- p = append(p, challengeKey...)
- p = append(p, "\r\n"...)
- for k, vs := range requestHeader {
- for _, v := range vs {
- p = append(p, k...)
- p = append(p, ": "...)
- p = append(p, v...)
- p = append(p, "\r\n"...)
- }
- }
- p = append(p, "\r\n"...)
-
- if _, err := netConn.Write(p); err != nil {
- return nil, nil, err
- }
-
- resp, err := http.ReadResponse(c.br, &http.Request{Method: "GET", URL: u})
- if err != nil {
- return nil, nil, err
- }
- if resp.StatusCode != 101 ||
- !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
- !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
- resp.Header.Get("Sec-Websocket-Accept") != acceptKey {
- return nil, resp, ErrBadHandshake
- }
- c.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
- return c, resp, nil
+ return d.Dial(u.String(), requestHeader)
}
// A Dialer contains options for connecting to WebSocket server.
@@ -82,6 +50,12 @@ type Dialer struct {
// NetDial is nil, net.Dial is used.
NetDial func(network, addr string) (net.Conn, error)
+ // Proxy specifies a function to return a proxy for a given
+ // Request. If the function returns a non-nil error, the
+ // request is aborted with the provided error.
+ // If Proxy is nil or returns a nil *URL, no proxy is used.
+ Proxy func(*http.Request) (*url.URL, error)
+
// TLSClientConfig specifies the TLS configuration to use with tls.Client.
// If nil, the default configuration is used.
TLSClientConfig *tls.Config
@@ -99,17 +73,15 @@ type Dialer struct {
var errMalformedURL = errors.New("malformed ws or wss URL")
-// parseURL parses the URL. The url.Parse function is not used here because
-// url.Parse mangles the path.
+// 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 ]
- //
- // We don't use the net/url parser here because the dialer interface does
- // not provide a way for applications to work around percent deocding in
- // the net/url parser.
var u url.URL
switch {
@@ -130,6 +102,12 @@ func parseURL(s string) (*url.URL, error) {
u.Opaque = s[i:]
}
+ 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
}
@@ -139,9 +117,12 @@ func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
hostNoPort = hostNoPort[:i]
} else {
- if u.Scheme == "wss" {
+ switch u.Scheme {
+ case "wss":
+ hostPort += ":443"
+ case "https":
hostPort += ":443"
- } else {
+ default:
hostPort += ":80"
}
}
@@ -149,7 +130,9 @@ func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
}
// DefaultDialer is a dialer with all fields set to the default zero values.
-var DefaultDialer *Dialer
+var DefaultDialer = &Dialer{
+ Proxy: http.ProxyFromEnvironment,
+}
// Dial creates a new client connection. Use requestHeader to specify the
// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
@@ -161,15 +144,91 @@ var DefaultDialer *Dialer
// etcetera. The response body may not contain the entire response and does not
// need to be closed by the application.
func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
+
+ if d == nil {
+ d = &Dialer{
+ Proxy: http.ProxyFromEnvironment,
+ }
+ }
+
+ challengeKey, err := generateChallengeKey()
+ if err != nil {
+ return nil, nil, err
+ }
+
u, err := parseURL(urlStr)
if err != nil {
return nil, nil, err
}
+ switch u.Scheme {
+ case "ws":
+ u.Scheme = "http"
+ case "wss":
+ u.Scheme = "https"
+ default:
+ return nil, nil, errMalformedURL
+ }
+
+ if u.User != nil {
+ // User name and password are not allowed in websocket URIs.
+ return nil, nil, errMalformedURL
+ }
+
+ req := &http.Request{
+ Method: "GET",
+ URL: u,
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Header: make(http.Header),
+ Host: u.Host,
+ }
+
+ // Set the request headers using the capitalization for names and values in
+ // RFC examples. Although the capitalization shouldn't matter, there are
+ // servers that depend on it. The Header.Set method is not used because the
+ // method canonicalizes the header names.
+ req.Header["Upgrade"] = []string{"websocket"}
+ req.Header["Connection"] = []string{"Upgrade"}
+ req.Header["Sec-WebSocket-Key"] = []string{challengeKey}
+ req.Header["Sec-WebSocket-Version"] = []string{"13"}
+ if len(d.Subprotocols) > 0 {
+ req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")}
+ }
+ for k, vs := range requestHeader {
+ switch {
+ case k == "Host":
+ if len(vs) > 0 {
+ req.Host = vs[0]
+ }
+ case k == "Upgrade" ||
+ k == "Connection" ||
+ k == "Sec-Websocket-Key" ||
+ k == "Sec-Websocket-Version" ||
+ (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
+ return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
+ default:
+ req.Header[k] = vs
+ }
+ }
+
hostPort, hostNoPort := hostPortNoPort(u)
- if d == nil {
- d = &Dialer{}
+ 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
@@ -183,7 +242,7 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
netDial = netDialer.Dial
}
- netConn, err := netDial("tcp", hostPort)
+ netConn, err := netDial("tcp", targetHostPort)
if err != nil {
return nil, nil, err
}
@@ -198,7 +257,31 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
return nil, nil, err
}
- if u.Scheme == "wss" {
+ if proxyURL != nil {
+ connectReq := &http.Request{
+ Method: "CONNECT",
+ URL: &url.URL{Opaque: hostPort},
+ Host: hostPort,
+ Header: make(http.Header),
+ }
+
+ 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 := d.TLSClientConfig
if cfg == nil {
cfg = &tls.Config{ServerName: hostNoPort}
@@ -219,45 +302,32 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
}
}
- if len(d.Subprotocols) > 0 {
- h := http.Header{}
- for k, v := range requestHeader {
- h[k] = v
- }
- h.Set("Sec-Websocket-Protocol", strings.Join(d.Subprotocols, ", "))
- requestHeader = h
- }
-
- if len(requestHeader["Host"]) > 0 {
- // This can be used to supply a Host: header which is different from
- // the dial address.
- u.Host = requestHeader.Get("Host")
+ conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize)
- // Drop "Host" header
- h := http.Header{}
- for k, v := range requestHeader {
- if k == "Host" {
- continue
- }
- h[k] = v
- }
- requestHeader = h
+ if err := req.Write(netConn); err != nil {
+ return nil, nil, err
}
- conn, resp, err := NewClient(netConn, u, requestHeader, d.ReadBufferSize, d.WriteBufferSize)
-
+ resp, err := http.ReadResponse(conn.br, req)
if err != nil {
- if err == ErrBadHandshake {
- // Before closing the network connection on return from this
- // function, slurp up some of the response to aid application
- // debugging.
- buf := make([]byte, 1024)
- n, _ := io.ReadFull(resp.Body, buf)
- resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
- }
- return nil, resp, err
+ return nil, nil, err
+ }
+ if resp.StatusCode != 101 ||
+ !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
+ !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
+ resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
+ // Before closing the network connection on return from this
+ // function, slurp up some of the response to aid application
+ // debugging.
+ buf := make([]byte, 1024)
+ n, _ := io.ReadFull(resp.Body, buf)
+ resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
+ return nil, resp, ErrBadHandshake
}
+ resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
+ conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
+
netConn.SetDeadline(time.Time{})
netConn = nil // to avoid close in defer.
return conn, resp, nil
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go b/Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go
index 749ef2050..05a7888fe 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/client_server_test.go
@@ -56,11 +56,6 @@ func newTLSServer(t *testing.T) *cstServer {
}
func (t cstHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if r.Method != "GET" {
- t.Logf("method %s not allowed", r.Method)
- http.Error(w, "method not allowed", 405)
- return
- }
subprotos := Subprotocols(r)
if !reflect.DeepEqual(subprotos, cstDialer.Subprotocols) {
t.Logf("subprotols=%v, want %v", subprotos, cstDialer.Subprotocols)
@@ -123,6 +118,45 @@ func sendRecv(t *testing.T, ws *Conn) {
}
}
+func TestProxyDial(t *testing.T) {
+
+ s := newServer(t)
+ defer s.Close()
+
+ surl, _ := url.Parse(s.URL)
+
+ 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 recieved")
+ http.Error(w, "connect not recieved", 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)
+
+ cstDialer.Proxy = http.ProxyFromEnvironment
+}
+
func TestDial(t *testing.T) {
s := newServer(t)
defer s.Close()
@@ -229,6 +263,45 @@ func TestDialBadOrigin(t *testing.T) {
}
}
+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()
+
+ resp, err := http.PostForm(s.URL, url.Values{})
+ if err != nil {
+ t.Fatalf("PostForm 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()
@@ -289,8 +362,8 @@ func TestRespOnBadHandshake(t *testing.T) {
}
}
-// If the Host header is specified in `Dial()`, the server must receive it as
-// the `Host:` header.
+// 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()
@@ -305,16 +378,12 @@ func TestHostHeader(t *testing.T) {
origHandler.ServeHTTP(w, r)
})
- ws, resp, err := cstDialer.Dial(s.URL, http.Header{"Host": {"testhost"}})
+ ws, _, err := cstDialer.Dial(s.URL, http.Header{"Host": {"testhost"}})
if err != nil {
t.Fatalf("Dial: %v", err)
}
defer ws.Close()
- if resp.StatusCode != http.StatusSwitchingProtocols {
- t.Fatalf("resp.StatusCode = %v, want http.StatusSwitchingProtocols", resp.StatusCode)
- }
-
if gotHost := <-specifiedHost; gotHost != "testhost" {
t.Fatalf("gotHost = %q, want \"testhost\"", gotHost)
}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go b/Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go
index d2f2ebd79..07a9cb453 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/client_test.go
@@ -20,6 +20,7 @@ var parseURLTests = []struct {
{"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"}},
{"ss://example.com/a/b", nil},
+ {"ws://webmaster@example.com/", nil},
}
func TestParseURL(t *testing.T) {
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/conn.go b/Godeps/_workspace/src/github.com/gorilla/websocket/conn.go
index e719f1ce6..e8b6b3e04 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/conn.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/conn.go
@@ -88,19 +88,23 @@ 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 close frame.
-type closeError struct {
- code int
- text string
+// CloseError represents close frame.
+type CloseError struct {
+
+ // Code is defined in RFC 6455, section 11.7.
+ Code int
+
+ // Text is the optional text payload.
+ Text string
}
-func (e *closeError) Error() string {
- return "websocket: close " + strconv.Itoa(e.code) + " " + e.text
+func (e *CloseError) Error() string {
+ return "websocket: close " + strconv.Itoa(e.Code) + " " + e.Text
}
var (
- errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true}
- errUnexpectedEOF = &closeError{code: CloseAbnormalClosure, text: io.ErrUnexpectedEOF.Error()}
+ errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
+ errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
errBadWriteOpCode = errors.New("websocket: bad write message type")
errWriteClosed = errors.New("websocket: write closed")
errInvalidControlFrame = errors.New("websocket: invalid control frame")
@@ -296,7 +300,7 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
if n != 0 && n != len(buf) {
c.conn.Close()
}
- return err
+ return hideTempErr(err)
}
// NextWriter returns a writer for the next message to send. The writer's
@@ -673,12 +677,7 @@ func (c *Conn) advanceFrame() (int, error) {
closeCode = int(binary.BigEndian.Uint16(payload))
closeText = string(payload[2:])
}
- switch closeCode {
- case CloseNormalClosure, CloseGoingAway:
- return noFrame, io.EOF
- default:
- return noFrame, &closeError{code: closeCode, text: closeText}
- }
+ return noFrame, &CloseError{Code: closeCode, Text: closeText}
}
return frameType, nil
@@ -790,20 +789,27 @@ func (c *Conn) SetReadLimit(limit int64) {
}
// SetPingHandler sets the handler for ping messages received from the peer.
-// The default ping handler sends a pong to the peer.
-func (c *Conn) SetPingHandler(h func(string) error) {
+// The appData argument to h is the PING frame application data. The default
+// ping handler sends a pong to the peer.
+func (c *Conn) SetPingHandler(h func(appData string) error) {
if h == nil {
h = func(message string) error {
- c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
- return nil
+ err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
+ if err == ErrCloseSent {
+ return nil
+ } else if e, ok := err.(net.Error); ok && e.Temporary() {
+ return nil
+ }
+ return err
}
}
c.handlePing = h
}
// SetPongHandler sets the handler for pong messages received from the peer.
-// The default pong handler does nothing.
-func (c *Conn) SetPongHandler(h func(string) error) {
+// The appData argument to h is the PONG frame application data. The default
+// pong handler does nothing.
+func (c *Conn) SetPongHandler(h func(appData string) error) {
if h == nil {
h = func(string) error { return nil }
}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go b/Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go
index 1f1197e71..02f2d4b50 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/conn_test.go
@@ -5,11 +5,13 @@
package websocket
import (
+ "bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"net"
+ "reflect"
"testing"
"testing/iotest"
"time"
@@ -146,13 +148,15 @@ func TestControl(t *testing.T) {
func TestCloseBeforeFinalFrame(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(CloseNormalClosure, ""), time.Now().Add(10*time.Second))
+ wc.WriteControl(CloseMessage, FormatCloseMessage(expectedErr.Code, expectedErr.Text), time.Now().Add(10*time.Second))
w.Close()
op, r, err := rc.NextReader()
@@ -160,12 +164,12 @@ func TestCloseBeforeFinalFrame(t *testing.T) {
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)
+ if !reflect.DeepEqual(err, expectedErr) {
+ t.Fatalf("io.Copy() returned %v, want %v", err, expectedErr)
}
_, _, err = rc.NextReader()
- if err != io.EOF {
- t.Fatalf("NextReader() returned %v, want %v", err, io.EOF)
+ if !reflect.DeepEqual(err, expectedErr) {
+ t.Fatalf("NextReader() returned %v, want %v", err, expectedErr)
}
}
@@ -236,3 +240,33 @@ func TestUnderlyingConn(t *testing.T) {
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 returnd %d bytes, want %d bytes", len(p), len(m))
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/doc.go b/Godeps/_workspace/src/github.com/gorilla/websocket/doc.go
index 0d2bd912b..72286279c 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/doc.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/doc.go
@@ -24,7 +24,7 @@
// ... Use conn to send and receive messages.
// }
//
-// Call the connection WriteMessage and ReadMessages methods to send and
+// Call the connection's WriteMessage and ReadMessage methods to send and
// receive messages as a slice of bytes. This snippet of code shows how to echo
// messages using these methods:
//
@@ -97,10 +97,13 @@
//
// Concurrency
//
-// Connections do not support concurrent calls to the write methods
-// (NextWriter, SetWriteDeadline, WriteMessage) or concurrent calls to the read
-// methods methods (NextReader, SetReadDeadline, ReadMessage). Connections do
-// support a concurrent reader and writer.
+// Connections support one concurrent reader and one concurrent writer.
+//
+// Applications are responsible for ensuring that no more than one goroutine
+// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
+// WriteJSON) concurrently and that no more than one goroutine calls the read
+// methods (NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler,
+// SetPingHandler) concurrently.
//
// The Close and WriteControl methods can be called concurrently with all other
// methods.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go
index d96ac84db..d0b1c3158 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go
@@ -8,7 +8,7 @@ package main
import (
"errors"
"flag"
- "github.com/gorilla/websocket"
+ "github.com/mattermost/platform/Godeps/_workspace/src/github.com/gorilla/websocket"
"io"
"log"
"net/http"
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
index 08fc3e65c..5df3cf1a3 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
@@ -17,3 +17,4 @@ using the following commands.
$ 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.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go
index 7cc0496c3..675d64113 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go
@@ -5,7 +5,7 @@
package main
import (
- "github.com/gorilla/websocket"
+ "github.com/mattermost/platform/Godeps/_workspace/src/github.com/gorilla/websocket"
"log"
"net/http"
"time"
@@ -88,12 +88,8 @@ func (c *connection) writePump() {
}
}
-// serverWs handles websocket requests from the peer.
+// serveWs handles websocket requests from the peer.
func serveWs(w http.ResponseWriter, r *http.Request) {
- if r.Method != "GET" {
- http.Error(w, "Method not allowed", 405)
- return
- }
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md
new file mode 100644
index 000000000..c30d3979a
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md
@@ -0,0 +1,19 @@
+# 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
+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/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html
new file mode 100644
index 000000000..72fd02b2a
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Command Example</title>
+<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
+<script type="text/javascript">
+ $(function() {
+
+ var conn;
+ var msg = $("#msg");
+ var log = $("#log");
+
+ function appendLog(msg) {
+ var d = log[0]
+ var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
+ msg.appendTo(log)
+ if (doScroll) {
+ d.scrollTop = d.scrollHeight - d.clientHeight;
+ }
+ }
+
+ $("#form").submit(function() {
+ if (!conn) {
+ return false;
+ }
+ if (!msg.val()) {
+ return false;
+ }
+ conn.send(msg.val());
+ msg.val("");
+ return false
+ });
+
+ if (window["WebSocket"]) {
+ conn = new WebSocket("ws://{{$}}/ws");
+ conn.onclose = function(evt) {
+ appendLog($("<div><b>Connection closed.</b></div>"))
+ }
+ conn.onmessage = function(evt) {
+ appendLog($("<pre/>").text(evt.data))
+ }
+ } else {
+ appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"))
+ }
+ });
+</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/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go
new file mode 100644
index 000000000..3531b368c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go
@@ -0,0 +1,188 @@
+// 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"
+ "text/template"
+ "time"
+
+ "github.com/mattermost/platform/Godeps/_workspace/src/github.com/gorilla/websocket"
+)
+
+var (
+ addr = flag.String("addr", "127.0.0.1:8080", "http service address")
+ cmdPath string
+ homeTempl = template.Must(template.ParseFiles("home.html"))
+)
+
+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
+)
+
+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() {
+ ws.Close()
+ close(done)
+ }()
+ s := bufio.NewScanner(r)
+ for s.Scan() {
+ ws.SetWriteDeadline(time.Now().Add(writeWait))
+ if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil {
+ break
+ }
+ }
+ if s.Err() != nil {
+ log.Println("scan:", s.Err())
+ }
+}
+
+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
+ }
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+ homeTempl.Execute(w, r.Host)
+}
+
+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/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md
new file mode 100644
index 000000000..6ad79ed76
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md
@@ -0,0 +1,17 @@
+# 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/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go
new file mode 100644
index 000000000..998d54462
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go
@@ -0,0 +1,55 @@
+// 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"
+ "time"
+
+ "github.com/mattermost/platform/Godeps/_workspace/src/github.com/gorilla/websocket"
+)
+
+var addr = flag.String("addr", "localhost:8080", "http service address")
+
+func main() {
+ flag.Parse()
+ log.SetFlags(0)
+
+ 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()
+
+ go func() {
+ defer c.Close()
+ for {
+ _, message, err := c.ReadMessage()
+ if err != nil {
+ log.Println("read:", err)
+ break
+ }
+ log.Printf("recv: %s", message)
+ }
+ }()
+
+ ticker := time.NewTicker(time.Second)
+ defer ticker.Stop()
+
+ for t := range ticker.C {
+ err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
+ if err != nil {
+ log.Println("write:", err)
+ break
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go
new file mode 100644
index 000000000..87f14ceb5
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go
@@ -0,0 +1,132 @@
+// 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/mattermost/platform/Godeps/_workspace/src/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>
+<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/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go
index a2c7b85fa..04244bc0f 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go
@@ -14,7 +14,7 @@ import (
"text/template"
"time"
- "github.com/gorilla/websocket"
+ "github.com/mattermost/platform/Godeps/_workspace/src/github.com/gorilla/websocket"
)
const (
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/json.go b/Godeps/_workspace/src/github.com/gorilla/websocket/json.go
index 18e62f225..4f0e36875 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/json.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/json.go
@@ -48,9 +48,7 @@ func (c *Conn) ReadJSON(v interface{}) error {
}
err = json.NewDecoder(r).Decode(v)
if err == io.EOF {
- // Decode returns io.EOF when the message is empty or all whitespace.
- // Convert to io.ErrUnexpectedEOF so that application can distinguish
- // between an error reading the JSON value and the connection closing.
+ // One value is expected in the message.
err = io.ErrUnexpectedEOF
}
return err
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go b/Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go
index 1b7a5ec8b..61100e481 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/json_test.go
@@ -38,7 +38,7 @@ func TestJSON(t *testing.T) {
}
}
-func TestPartialJsonRead(t *testing.T) {
+func TestPartialJSONRead(t *testing.T) {
var buf bytes.Buffer
c := fakeNetConn{&buf, &buf}
wc := newConn(c, true, 1024, 1024)
@@ -87,7 +87,7 @@ func TestPartialJsonRead(t *testing.T) {
}
err = rc.ReadJSON(&v)
- if err != io.EOF {
+ if _, ok := err.(*CloseError); !ok {
t.Error("final", err)
}
}
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/server.go
index e56a00493..3a9805f02 100644
--- a/Godeps/_workspace/src/github.com/gorilla/websocket/server.go
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/server.go
@@ -93,6 +93,9 @@ func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
// application negotiated subprotocol (Sec-Websocket-Protocol).
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
+ if r.Method != "GET" {
+ return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: method not GET")
+ }
if values := r.Header["Sec-Websocket-Version"]; len(values) == 0 || values[0] != "13" {
return u.returnError(w, r, http.StatusBadRequest, "websocket: version != 13")
}