diff --git a/accept.go b/accept.go index 75d6d643e2d39e238b308a8a520bf2d10670cfa1..fda8cdc679fb7f9fad6d99e363063b38596ac2f8 100644 --- a/accept.go +++ b/accept.go @@ -6,14 +6,14 @@ import ( "bytes" "crypto/sha1" "encoding/base64" + "errors" + "fmt" "io" "net/http" "net/textproto" "net/url" "strings" - "golang.org/x/xerrors" - "nhooyr.io/websocket/internal/errd" ) @@ -85,7 +85,7 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con hj, ok := w.(http.Hijacker) if !ok { - err = xerrors.New("http.ResponseWriter does not implement http.Hijacker") + err = errors.New("http.ResponseWriter does not implement http.Hijacker") http.Error(w, http.StatusText(http.StatusNotImplemented), http.StatusNotImplemented) return nil, err } @@ -110,7 +110,7 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con netConn, brw, err := hj.Hijack() if err != nil { - err = xerrors.Errorf("failed to hijack connection: %w", err) + err = fmt.Errorf("failed to hijack connection: %w", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return nil, err } @@ -133,32 +133,32 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con func verifyClientRequest(w http.ResponseWriter, r *http.Request) (errCode int, _ error) { if !r.ProtoAtLeast(1, 1) { - return http.StatusUpgradeRequired, xerrors.Errorf("WebSocket protocol violation: handshake request must be at least HTTP/1.1: %q", r.Proto) + return http.StatusUpgradeRequired, fmt.Errorf("WebSocket protocol violation: handshake request must be at least HTTP/1.1: %q", r.Proto) } if !headerContainsToken(r.Header, "Connection", "Upgrade") { w.Header().Set("Connection", "Upgrade") w.Header().Set("Upgrade", "websocket") - return http.StatusUpgradeRequired, xerrors.Errorf("WebSocket protocol violation: Connection header %q does not contain Upgrade", r.Header.Get("Connection")) + return http.StatusUpgradeRequired, fmt.Errorf("WebSocket protocol violation: Connection header %q does not contain Upgrade", r.Header.Get("Connection")) } if !headerContainsToken(r.Header, "Upgrade", "websocket") { w.Header().Set("Connection", "Upgrade") w.Header().Set("Upgrade", "websocket") - return http.StatusUpgradeRequired, xerrors.Errorf("WebSocket protocol violation: Upgrade header %q does not contain websocket", r.Header.Get("Upgrade")) + return http.StatusUpgradeRequired, fmt.Errorf("WebSocket protocol violation: Upgrade header %q does not contain websocket", r.Header.Get("Upgrade")) } if r.Method != "GET" { - return http.StatusMethodNotAllowed, xerrors.Errorf("WebSocket protocol violation: handshake request method is not GET but %q", r.Method) + return http.StatusMethodNotAllowed, fmt.Errorf("WebSocket protocol violation: handshake request method is not GET but %q", r.Method) } if r.Header.Get("Sec-WebSocket-Version") != "13" { w.Header().Set("Sec-WebSocket-Version", "13") - return http.StatusBadRequest, xerrors.Errorf("unsupported WebSocket protocol version (only 13 is supported): %q", r.Header.Get("Sec-WebSocket-Version")) + return http.StatusBadRequest, fmt.Errorf("unsupported WebSocket protocol version (only 13 is supported): %q", r.Header.Get("Sec-WebSocket-Version")) } if r.Header.Get("Sec-WebSocket-Key") == "" { - return http.StatusBadRequest, xerrors.New("WebSocket protocol violation: missing Sec-WebSocket-Key") + return http.StatusBadRequest, errors.New("WebSocket protocol violation: missing Sec-WebSocket-Key") } return 0, nil @@ -169,10 +169,10 @@ func authenticateOrigin(r *http.Request) error { if origin != "" { u, err := url.Parse(origin) if err != nil { - return xerrors.Errorf("failed to parse Origin header %q: %w", origin, err) + return fmt.Errorf("failed to parse Origin header %q: %w", origin, err) } if !strings.EqualFold(u.Host, r.Host) { - return xerrors.Errorf("request Origin %q is not authorized for Host %q", origin, r.Host) + return fmt.Errorf("request Origin %q is not authorized for Host %q", origin, r.Host) } } return nil @@ -223,7 +223,7 @@ func acceptDeflate(w http.ResponseWriter, ext websocketExtension, mode Compressi continue } - err := xerrors.Errorf("unsupported permessage-deflate parameter: %q", p) + err := fmt.Errorf("unsupported permessage-deflate parameter: %q", p) http.Error(w, err.Error(), http.StatusBadRequest) return nil, err } @@ -253,7 +253,7 @@ func acceptWebkitDeflate(w http.ResponseWriter, ext websocketExtension, mode Com // // Either way, we're only implementing this for webkit which never sends the max_window_bits // parameter so we don't need to worry about it. - err := xerrors.Errorf("unsupported x-webkit-deflate-frame parameter: %q", p) + err := fmt.Errorf("unsupported x-webkit-deflate-frame parameter: %q", p) http.Error(w, err.Error(), http.StatusBadRequest) return nil, err } diff --git a/accept_js.go b/accept_js.go index 5db12d7bc12b0a5770c117c09b18c2714e9009ab..724b35b5bc3e4712a3a8d4299c587ba2d47e7fef 100644 --- a/accept_js.go +++ b/accept_js.go @@ -1,9 +1,8 @@ package websocket import ( + "errors" "net/http" - - "golang.org/x/xerrors" ) // AcceptOptions represents Accept's options. @@ -16,5 +15,5 @@ type AcceptOptions struct { // Accept is stubbed out for Wasm. func Accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (*Conn, error) { - return nil, xerrors.New("unimplemented") + return nil, errors.New("unimplemented") } diff --git a/accept_test.go b/accept_test.go index 53338e1781da8aac86376f7fd9f71cf3b43831c7..523d4685291ea5c9b60fa3b9db81a05334bad835 100644 --- a/accept_test.go +++ b/accept_test.go @@ -4,14 +4,13 @@ package websocket import ( "bufio" + "errors" "net" "net/http" "net/http/httptest" "strings" "testing" - "golang.org/x/xerrors" - "nhooyr.io/websocket/internal/test/assert" ) @@ -80,7 +79,7 @@ func TestAccept(t *testing.T) { w := mockHijacker{ ResponseWriter: httptest.NewRecorder(), hijack: func() (conn net.Conn, writer *bufio.ReadWriter, err error) { - return nil, nil, xerrors.New("haha") + return nil, nil, errors.New("haha") }, } diff --git a/autobahn_test.go b/autobahn_test.go index fb24a06bb9e4058db4103d20a72100b39c1d265d..504735340e2676297b6b053c70e391ea2c9b0e72 100644 --- a/autobahn_test.go +++ b/autobahn_test.go @@ -15,8 +15,6 @@ import ( "testing" "time" - "golang.org/x/xerrors" - "nhooyr.io/websocket" "nhooyr.io/websocket/internal/errd" "nhooyr.io/websocket/internal/test/assert" @@ -108,7 +106,7 @@ func wstestClientServer(ctx context.Context) (url string, closeFn func(), err er "exclude-cases": excludedAutobahnCases, }) if err != nil { - return "", nil, xerrors.Errorf("failed to write spec: %w", err) + return "", nil, fmt.Errorf("failed to write spec: %w", err) } ctx, cancel := context.WithTimeout(context.Background(), time.Minute*15) @@ -126,7 +124,7 @@ func wstestClientServer(ctx context.Context) (url string, closeFn func(), err er wstest := exec.CommandContext(ctx, "wstest", args...) err = wstest.Start() if err != nil { - return "", nil, xerrors.Errorf("failed to start wstest: %w", err) + return "", nil, fmt.Errorf("failed to start wstest: %w", err) } return url, func() { @@ -209,7 +207,7 @@ func unusedListenAddr() (_ string, err error) { func tempJSONFile(v interface{}) (string, error) { f, err := ioutil.TempFile("", "temp.json") if err != nil { - return "", xerrors.Errorf("temp file: %w", err) + return "", fmt.Errorf("temp file: %w", err) } defer f.Close() @@ -217,12 +215,12 @@ func tempJSONFile(v interface{}) (string, error) { e.SetIndent("", "\t") err = e.Encode(v) if err != nil { - return "", xerrors.Errorf("json encode: %w", err) + return "", fmt.Errorf("json encode: %w", err) } err = f.Close() if err != nil { - return "", xerrors.Errorf("close temp file: %w", err) + return "", fmt.Errorf("close temp file: %w", err) } return f.Name(), nil diff --git a/close.go b/close.go index 200732330d7b60e55e546dedd5991a4d95f3398f..7cbc19e9def65c647bf9f757e9b0018d488eaf69 100644 --- a/close.go +++ b/close.go @@ -1,9 +1,8 @@ package websocket import ( + "errors" "fmt" - - "golang.org/x/xerrors" ) // StatusCode represents a WebSocket status code. @@ -53,7 +52,7 @@ const ( // CloseError is returned when the connection is closed with a status and reason. // -// Use Go 1.13's xerrors.As to check for this error. +// Use Go 1.13's errors.As to check for this error. // Also see the CloseStatus helper. type CloseError struct { Code StatusCode @@ -64,13 +63,13 @@ func (ce CloseError) Error() string { return fmt.Sprintf("status = %v and reason = %q", ce.Code, ce.Reason) } -// CloseStatus is a convenience wrapper around Go 1.13's xerrors.As to grab +// CloseStatus is a convenience wrapper around Go 1.13's errors.As to grab // the status code from a CloseError. // // -1 will be returned if the passed error is nil or not a CloseError. func CloseStatus(err error) StatusCode { var ce CloseError - if xerrors.As(err, &ce) { + if errors.As(err, &ce) { return ce.Code } return -1 diff --git a/close_notjs.go b/close_notjs.go index 3367ea0134710dd5da9000cc979b6e9cd9f3bf55..c25b088f19bad5f6a25a5ea76f633470608eebd8 100644 --- a/close_notjs.go +++ b/close_notjs.go @@ -5,11 +5,11 @@ package websocket import ( "context" "encoding/binary" + "errors" + "fmt" "log" "time" - "golang.org/x/xerrors" - "nhooyr.io/websocket/internal/errd" ) @@ -46,7 +46,7 @@ func (c *Conn) closeHandshake(code StatusCode, reason string) (err error) { return nil } -var errAlreadyWroteClose = xerrors.New("already wrote close") +var errAlreadyWroteClose = errors.New("already wrote close") func (c *Conn) writeClose(code StatusCode, reason string) error { c.closeMu.Lock() @@ -62,7 +62,7 @@ func (c *Conn) writeClose(code StatusCode, reason string) error { Reason: reason, } - c.setCloseErr(xerrors.Errorf("sent close frame: %w", ce)) + c.setCloseErr(fmt.Errorf("sent close frame: %w", ce)) var p []byte var err error @@ -119,7 +119,7 @@ func parseClosePayload(p []byte) (CloseError, error) { } if len(p) < 2 { - return CloseError{}, xerrors.Errorf("close payload %q too small, cannot even contain the 2 byte status code", p) + return CloseError{}, fmt.Errorf("close payload %q too small, cannot even contain the 2 byte status code", p) } ce := CloseError{ @@ -128,7 +128,7 @@ func parseClosePayload(p []byte) (CloseError, error) { } if !validWireCloseCode(ce.Code) { - return CloseError{}, xerrors.Errorf("invalid status code %v", ce.Code) + return CloseError{}, fmt.Errorf("invalid status code %v", ce.Code) } return ce, nil @@ -155,7 +155,7 @@ func validWireCloseCode(code StatusCode) bool { func (ce CloseError) bytes() ([]byte, error) { p, err := ce.bytesErr() if err != nil { - err = xerrors.Errorf("failed to marshal close frame: %w", err) + err = fmt.Errorf("failed to marshal close frame: %w", err) ce = CloseError{ Code: StatusInternalError, } @@ -168,11 +168,11 @@ const maxCloseReason = maxControlPayload - 2 func (ce CloseError) bytesErr() ([]byte, error) { if len(ce.Reason) > maxCloseReason { - return nil, xerrors.Errorf("reason string max is %v but got %q with length %v", maxCloseReason, ce.Reason, len(ce.Reason)) + return nil, fmt.Errorf("reason string max is %v but got %q with length %v", maxCloseReason, ce.Reason, len(ce.Reason)) } if !validWireCloseCode(ce.Code) { - return nil, xerrors.Errorf("status code %v cannot be set", ce.Code) + return nil, fmt.Errorf("status code %v cannot be set", ce.Code) } buf := make([]byte, 2+len(ce.Reason)) @@ -189,7 +189,7 @@ func (c *Conn) setCloseErr(err error) { func (c *Conn) setCloseErrLocked(err error) { if c.closeErr == nil { - c.closeErr = xerrors.Errorf("WebSocket closed: %w", err) + c.closeErr = fmt.Errorf("WebSocket closed: %w", err) } } diff --git a/conn_notjs.go b/conn_notjs.go index 8598ded38fff1fc295e24dc4316016fab4658bc8..7ee60fbc300ea249fdd30535e92093f5a52ebd71 100644 --- a/conn_notjs.go +++ b/conn_notjs.go @@ -5,13 +5,13 @@ package websocket import ( "bufio" "context" + "errors" + "fmt" "io" "runtime" "strconv" "sync" "sync/atomic" - - "golang.org/x/xerrors" ) // Conn represents a WebSocket connection. @@ -108,7 +108,7 @@ func newConn(cfg connConfig) *Conn { } runtime.SetFinalizer(c, func(c *Conn) { - c.close(xerrors.New("connection garbage collected")) + c.close(errors.New("connection garbage collected")) }) go c.timeoutLoop() @@ -165,10 +165,10 @@ func (c *Conn) timeoutLoop() { case readCtx = <-c.readTimeout: case <-readCtx.Done(): - c.setCloseErr(xerrors.Errorf("read timed out: %w", readCtx.Err())) - go c.writeError(StatusPolicyViolation, xerrors.New("timed out")) + c.setCloseErr(fmt.Errorf("read timed out: %w", readCtx.Err())) + go c.writeError(StatusPolicyViolation, errors.New("timed out")) case <-writeCtx.Done(): - c.close(xerrors.Errorf("write timed out: %w", writeCtx.Err())) + c.close(fmt.Errorf("write timed out: %w", writeCtx.Err())) return } } @@ -190,7 +190,7 @@ func (c *Conn) Ping(ctx context.Context) error { err := c.ping(ctx, strconv.Itoa(int(p))) if err != nil { - return xerrors.Errorf("failed to ping: %w", err) + return fmt.Errorf("failed to ping: %w", err) } return nil } @@ -217,7 +217,7 @@ func (c *Conn) ping(ctx context.Context, p string) error { case <-c.closed: return c.closeErr case <-ctx.Done(): - err := xerrors.Errorf("failed to wait for pong: %w", ctx.Err()) + err := fmt.Errorf("failed to wait for pong: %w", ctx.Err()) c.close(err) return err case <-pong: @@ -242,7 +242,7 @@ func (m *mu) Lock(ctx context.Context) error { case <-m.c.closed: return m.c.closeErr case <-ctx.Done(): - err := xerrors.Errorf("failed to acquire lock: %w", ctx.Err()) + err := fmt.Errorf("failed to acquire lock: %w", ctx.Err()) m.c.close(err) return err case m.ch <- struct{}{}: diff --git a/conn_test.go b/conn_test.go index 7755048cc37e11b217e3816704d5ecb7a1fa16a8..c68a25f66522d5596ddb272c80ee6af90b7ad19b 100644 --- a/conn_test.go +++ b/conn_test.go @@ -19,7 +19,6 @@ import ( "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/duration" - "golang.org/x/xerrors" "nhooyr.io/websocket" "nhooyr.io/websocket/internal/test/assert" @@ -289,10 +288,10 @@ func TestWasm(t *testing.T) { func assertCloseStatus(exp websocket.StatusCode, err error) error { if websocket.CloseStatus(err) == -1 { - return xerrors.Errorf("expected websocket.CloseError: %T %v", err, err) + return fmt.Errorf("expected websocket.CloseError: %T %v", err, err) } if websocket.CloseStatus(err) != exp { - return xerrors.Errorf("expected close status %v but got ", exp, err) + return fmt.Errorf("expected close status %v but got %v", exp, err) } return nil } diff --git a/dial.go b/dial.go index 09546ac65b327f670da30aa9dfa93e7ab42732a1..6e37a589b2ad0500fc7302118a0793a8afa316c6 100644 --- a/dial.go +++ b/dial.go @@ -8,6 +8,8 @@ import ( "context" "crypto/rand" "encoding/base64" + "errors" + "fmt" "io" "io/ioutil" "net/http" @@ -15,8 +17,6 @@ import ( "strings" "sync" - "golang.org/x/xerrors" - "nhooyr.io/websocket/internal/errd" ) @@ -78,7 +78,7 @@ func dial(ctx context.Context, urls string, opts *DialOptions, rand io.Reader) ( secWebSocketKey, err := secWebSocketKey(rand) if err != nil { - return nil, nil, xerrors.Errorf("failed to generate Sec-WebSocket-Key: %w", err) + return nil, nil, fmt.Errorf("failed to generate Sec-WebSocket-Key: %w", err) } resp, err := handshakeRequest(ctx, urls, opts, secWebSocketKey) @@ -104,7 +104,7 @@ func dial(ctx context.Context, urls string, opts *DialOptions, rand io.Reader) ( rwc, ok := respBody.(io.ReadWriteCloser) if !ok { - return nil, resp, xerrors.Errorf("response body is not a io.ReadWriteCloser: %T", respBody) + return nil, resp, fmt.Errorf("response body is not a io.ReadWriteCloser: %T", respBody) } return newConn(connConfig{ @@ -120,12 +120,12 @@ func dial(ctx context.Context, urls string, opts *DialOptions, rand io.Reader) ( func handshakeRequest(ctx context.Context, urls string, opts *DialOptions, secWebSocketKey string) (*http.Response, error) { if opts.HTTPClient.Timeout > 0 { - return nil, xerrors.New("use context for cancellation instead of http.Client.Timeout; see https://github.com/nhooyr/websocket/issues/67") + return nil, errors.New("use context for cancellation instead of http.Client.Timeout; see https://github.com/nhooyr/websocket/issues/67") } u, err := url.Parse(urls) if err != nil { - return nil, xerrors.Errorf("failed to parse url: %w", err) + return nil, fmt.Errorf("failed to parse url: %w", err) } switch u.Scheme { @@ -134,7 +134,7 @@ func handshakeRequest(ctx context.Context, urls string, opts *DialOptions, secWe case "wss": u.Scheme = "https" default: - return nil, xerrors.Errorf("unexpected url scheme: %q", u.Scheme) + return nil, fmt.Errorf("unexpected url scheme: %q", u.Scheme) } req, _ := http.NewRequestWithContext(ctx, "GET", u.String(), nil) @@ -153,7 +153,7 @@ func handshakeRequest(ctx context.Context, urls string, opts *DialOptions, secWe resp, err := opts.HTTPClient.Do(req) if err != nil { - return nil, xerrors.Errorf("failed to send handshake request: %w", err) + return nil, fmt.Errorf("failed to send handshake request: %w", err) } return resp, nil } @@ -165,26 +165,26 @@ func secWebSocketKey(rr io.Reader) (string, error) { b := make([]byte, 16) _, err := io.ReadFull(rr, b) if err != nil { - return "", xerrors.Errorf("failed to read random data from rand.Reader: %w", err) + return "", fmt.Errorf("failed to read random data from rand.Reader: %w", err) } return base64.StdEncoding.EncodeToString(b), nil } func verifyServerResponse(opts *DialOptions, secWebSocketKey string, resp *http.Response) (*compressionOptions, error) { if resp.StatusCode != http.StatusSwitchingProtocols { - return nil, xerrors.Errorf("expected handshake response status code %v but got %v", http.StatusSwitchingProtocols, resp.StatusCode) + return nil, fmt.Errorf("expected handshake response status code %v but got %v", http.StatusSwitchingProtocols, resp.StatusCode) } if !headerContainsToken(resp.Header, "Connection", "Upgrade") { - return nil, xerrors.Errorf("WebSocket protocol violation: Connection header %q does not contain Upgrade", resp.Header.Get("Connection")) + return nil, fmt.Errorf("WebSocket protocol violation: Connection header %q does not contain Upgrade", resp.Header.Get("Connection")) } if !headerContainsToken(resp.Header, "Upgrade", "WebSocket") { - return nil, xerrors.Errorf("WebSocket protocol violation: Upgrade header %q does not contain websocket", resp.Header.Get("Upgrade")) + return nil, fmt.Errorf("WebSocket protocol violation: Upgrade header %q does not contain websocket", resp.Header.Get("Upgrade")) } if resp.Header.Get("Sec-WebSocket-Accept") != secWebSocketAccept(secWebSocketKey) { - return nil, xerrors.Errorf("WebSocket protocol violation: invalid Sec-WebSocket-Accept %q, key %q", + return nil, fmt.Errorf("WebSocket protocol violation: invalid Sec-WebSocket-Accept %q, key %q", resp.Header.Get("Sec-WebSocket-Accept"), secWebSocketKey, ) @@ -210,7 +210,7 @@ func verifySubprotocol(subprotos []string, resp *http.Response) error { } } - return xerrors.Errorf("WebSocket protocol violation: unexpected Sec-WebSocket-Protocol from server: %q", proto) + return fmt.Errorf("WebSocket protocol violation: unexpected Sec-WebSocket-Protocol from server: %q", proto) } func verifyServerExtensions(h http.Header) (*compressionOptions, error) { @@ -221,7 +221,7 @@ func verifyServerExtensions(h http.Header) (*compressionOptions, error) { ext := exts[0] if ext.name != "permessage-deflate" || len(exts) > 1 { - return nil, xerrors.Errorf("WebSocket protcol violation: unsupported extensions from server: %+v", exts[1:]) + return nil, fmt.Errorf("WebSocket protcol violation: unsupported extensions from server: %+v", exts[1:]) } copts := &compressionOptions{} @@ -232,7 +232,7 @@ func verifyServerExtensions(h http.Header) (*compressionOptions, error) { case "server_no_context_takeover": copts.serverNoContextTakeover = true default: - return nil, xerrors.Errorf("unsupported permessage-deflate parameter: %q", p) + return nil, fmt.Errorf("unsupported permessage-deflate parameter: %q", p) } } diff --git a/example_echo_test.go b/example_echo_test.go index 1daec8a571d72ed86c344f447685a871030ac785..cd195d2e1eea95e14109833272728ff171dcf963 100644 --- a/example_echo_test.go +++ b/example_echo_test.go @@ -4,6 +4,7 @@ package websocket_test import ( "context" + "errors" "fmt" "io" "log" @@ -12,7 +13,6 @@ import ( "time" "golang.org/x/time/rate" - "golang.org/x/xerrors" "nhooyr.io/websocket" "nhooyr.io/websocket/wsjson" @@ -78,7 +78,7 @@ func echoServer(w http.ResponseWriter, r *http.Request) error { if c.Subprotocol() != "echo" { c.Close(websocket.StatusPolicyViolation, "client must speak the echo subprotocol") - return xerrors.New("client does not speak echo sub protocol") + return errors.New("client does not speak echo sub protocol") } l := rate.NewLimiter(rate.Every(time.Millisecond*100), 10) @@ -88,7 +88,7 @@ func echoServer(w http.ResponseWriter, r *http.Request) error { return nil } if err != nil { - return xerrors.Errorf("failed to echo with %v: %w", r.RemoteAddr, err) + return fmt.Errorf("failed to echo with %v: %w", r.RemoteAddr, err) } } } @@ -117,7 +117,7 @@ func echo(ctx context.Context, c *websocket.Conn, l *rate.Limiter) error { _, err = io.Copy(w, r) if err != nil { - return xerrors.Errorf("failed to io.Copy: %w", err) + return fmt.Errorf("failed to io.Copy: %w", err) } err = w.Close() diff --git a/frame.go b/frame.go index 4acaecf43ff6c9a8eedad12b0e5a52a29af14ae5..2a036f944ac96962d987d8c730b651c8aad421ea 100644 --- a/frame.go +++ b/frame.go @@ -3,12 +3,11 @@ package websocket import ( "bufio" "encoding/binary" + "fmt" "io" "math" "math/bits" - "golang.org/x/xerrors" - "nhooyr.io/websocket/internal/errd" ) @@ -87,7 +86,7 @@ func readFrameHeader(r *bufio.Reader, readBuf []byte) (h header, err error) { } if h.payloadLength < 0 { - return header{}, xerrors.Errorf("received negative payload length: %v", h.payloadLength) + return header{}, fmt.Errorf("received negative payload length: %v", h.payloadLength) } if h.masked { diff --git a/go.mod b/go.mod index a10c7b1e3e53dde31226a820586acdb7f6624fa8..801d6be6d47b6874dfe767294d5ced67a6bac276 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module nhooyr.io/websocket -go 1.12 +go 1.13 require ( github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee // indirect @@ -11,5 +11,4 @@ require ( github.com/gorilla/websocket v1.4.1 github.com/klauspost/compress v1.10.0 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 ) diff --git a/internal/errd/wrap.go b/internal/errd/wrap.go index ed0b775447d005dce617f8a5b961dc6a3684cf3c..6e779131af8b64a481b37dfd24be7f03b98f6132 100644 --- a/internal/errd/wrap.go +++ b/internal/errd/wrap.go @@ -2,41 +2,13 @@ package errd import ( "fmt" - - "golang.org/x/xerrors" ) -type wrapError struct { - msg string - err error - frame xerrors.Frame -} - -func (e *wrapError) Error() string { - return fmt.Sprint(e) -} - -func (e *wrapError) Format(s fmt.State, v rune) { xerrors.FormatError(e, s, v) } - -func (e *wrapError) FormatError(p xerrors.Printer) (next error) { - p.Print(e.msg) - e.frame.Format(p) - return e.err -} - -func (e *wrapError) Unwrap() error { - return e.err -} - -// Wrap wraps err with xerrors.Errorf if err is non nil. +// Wrap wraps err with fmt.Errorf if err is non nil. // Intended for use with defer and a named error return. // Inspired by https://github.com/golang/go/issues/32676. func Wrap(err *error, f string, v ...interface{}) { if *err != nil { - *err = &wrapError{ - msg: fmt.Sprintf(f, v...), - err: *err, - frame: xerrors.Caller(1), - } + *err = fmt.Errorf(f+": %w", append(v, *err)...) } } diff --git a/internal/test/wstest/echo.go b/internal/test/wstest/echo.go index 714767fc40751e2822b46c7a58622d125b6a764e..ab7bc25aac53538cba61a137c7f4e1321ad5e49f 100644 --- a/internal/test/wstest/echo.go +++ b/internal/test/wstest/echo.go @@ -3,11 +3,10 @@ package wstest import ( "bytes" "context" + "fmt" "io" "time" - "golang.org/x/xerrors" - "nhooyr.io/websocket" "nhooyr.io/websocket/internal/test/cmp" "nhooyr.io/websocket/internal/test/xrand" @@ -73,11 +72,11 @@ func Echo(ctx context.Context, c *websocket.Conn, max int) error { } if expType != actType { - return xerrors.Errorf("unexpected message typ (%v): %v", expType, actType) + return fmt.Errorf("unexpected message typ (%v): %v", expType, actType) } if !bytes.Equal(msg, act) { - return xerrors.Errorf("unexpected msg read: %v", cmp.Diff(msg, act)) + return fmt.Errorf("unexpected msg read: %v", cmp.Diff(msg, act)) } return nil diff --git a/internal/test/wstest/pipe.go b/internal/test/wstest/pipe.go index 81705a8a7937533b7f2a5947cd5777ba2469ae23..0a2899ee1bba1c0131a8b5881c396f463afd7f12 100644 --- a/internal/test/wstest/pipe.go +++ b/internal/test/wstest/pipe.go @@ -5,12 +5,11 @@ package wstest import ( "bufio" "context" + "fmt" "net" "net/http" "net/http/httptest" - "golang.org/x/xerrors" - "nhooyr.io/websocket" "nhooyr.io/websocket/internal/errd" "nhooyr.io/websocket/internal/test/xrand" @@ -39,11 +38,11 @@ func Pipe(dialOpts *websocket.DialOptions, acceptOpts *websocket.AcceptOptions) clientConn, _, err := websocket.Dial(context.Background(), "ws://example.com", dialOpts) if err != nil { - return nil, nil, xerrors.Errorf("failed to dial with fake transport: %w", err) + return nil, nil, fmt.Errorf("failed to dial with fake transport: %w", err) } if serverConn == nil { - return nil, nil, xerrors.Errorf("failed to get server conn from fake transport: %w", acceptErr) + return nil, nil, fmt.Errorf("failed to get server conn from fake transport: %w", acceptErr) } if xrand.Bool() { diff --git a/internal/xsync/go.go b/internal/xsync/go.go index 712739aa2fa5b6484629c47a5aa41c1a80f1bd7b..7a61f27fa2ae24e1a699e0c205287c5407dc5729 100644 --- a/internal/xsync/go.go +++ b/internal/xsync/go.go @@ -1,7 +1,7 @@ package xsync import ( - "golang.org/x/xerrors" + "fmt" ) // Go allows running a function in another goroutine @@ -13,7 +13,7 @@ func Go(fn func() error) <-chan error { r := recover() if r != nil { select { - case errs <- xerrors.Errorf("panic in go fn: %v", r): + case errs <- fmt.Errorf("panic in go fn: %v", r): default: } } diff --git a/netconn.go b/netconn.go index a2d8f4f3ef313d61636ec13060dfa7ff528f4d33..64aadf0b998e374bce027f3255822480d6bb1a3e 100644 --- a/netconn.go +++ b/netconn.go @@ -2,13 +2,12 @@ package websocket import ( "context" + "fmt" "io" "math" "net" "sync" "time" - - "golang.org/x/xerrors" ) // NetConn converts a *websocket.Conn into a net.Conn. @@ -108,7 +107,7 @@ func (c *netConn) Read(p []byte) (int, error) { return 0, err } if typ != c.msgType { - err := xerrors.Errorf("unexpected frame type read (expected %v): %v", c.msgType, typ) + err := fmt.Errorf("unexpected frame type read (expected %v): %v", c.msgType, typ) c.c.Close(StatusUnsupportedData, err.Error()) return 0, err } diff --git a/read.go b/read.go index bbad30d14e59f43be73cab8176b9c0cdd14f6216..a1efecabb269c1efceacab1557962cebb54841fa 100644 --- a/read.go +++ b/read.go @@ -5,13 +5,13 @@ package websocket import ( "bufio" "context" + "errors" + "fmt" "io" "io/ioutil" "strings" "time" - "golang.org/x/xerrors" - "nhooyr.io/websocket/internal/errd" "nhooyr.io/websocket/internal/xsync" ) @@ -144,13 +144,13 @@ func (c *Conn) readLoop(ctx context.Context) (header, error) { } if h.rsv1 && c.readRSV1Illegal(h) || h.rsv2 || h.rsv3 { - err := xerrors.Errorf("received header with unexpected rsv bits set: %v:%v:%v", h.rsv1, h.rsv2, h.rsv3) + err := fmt.Errorf("received header with unexpected rsv bits set: %v:%v:%v", h.rsv1, h.rsv2, h.rsv3) c.writeError(StatusProtocolError, err) return header{}, err } if !c.client && !h.masked { - return header{}, xerrors.New("received unmasked frame from client") + return header{}, errors.New("received unmasked frame from client") } switch h.opcode { @@ -161,12 +161,12 @@ func (c *Conn) readLoop(ctx context.Context) (header, error) { if h.opcode == opClose && CloseStatus(err) != -1 { return header{}, err } - return header{}, xerrors.Errorf("failed to handle control frame %v: %w", h.opcode, err) + return header{}, fmt.Errorf("failed to handle control frame %v: %w", h.opcode, err) } case opContinuation, opText, opBinary: return h, nil default: - err := xerrors.Errorf("received unknown opcode %v", h.opcode) + err := fmt.Errorf("received unknown opcode %v", h.opcode) c.writeError(StatusProtocolError, err) return header{}, err } @@ -217,7 +217,7 @@ func (c *Conn) readFramePayload(ctx context.Context, p []byte) (int, error) { case <-ctx.Done(): return n, ctx.Err() default: - err = xerrors.Errorf("failed to read frame payload: %w", err) + err = fmt.Errorf("failed to read frame payload: %w", err) c.close(err) return n, err } @@ -234,13 +234,13 @@ func (c *Conn) readFramePayload(ctx context.Context, p []byte) (int, error) { func (c *Conn) handleControl(ctx context.Context, h header) (err error) { if h.payloadLength < 0 || h.payloadLength > maxControlPayload { - err := xerrors.Errorf("received control frame payload with invalid length: %d", h.payloadLength) + err := fmt.Errorf("received control frame payload with invalid length: %d", h.payloadLength) c.writeError(StatusProtocolError, err) return err } if !h.fin { - err := xerrors.New("received fragmented control frame") + err := errors.New("received fragmented control frame") c.writeError(StatusProtocolError, err) return err } @@ -277,12 +277,12 @@ func (c *Conn) handleControl(ctx context.Context, h header) (err error) { ce, err := parseClosePayload(b) if err != nil { - err = xerrors.Errorf("received invalid close payload: %w", err) + err = fmt.Errorf("received invalid close payload: %w", err) c.writeError(StatusProtocolError, err) return err } - err = xerrors.Errorf("received close frame: %w", ce) + err = fmt.Errorf("received close frame: %w", ce) c.setCloseErr(err) c.writeClose(ce.Code, ce.Reason) c.close(err) @@ -299,7 +299,7 @@ func (c *Conn) reader(ctx context.Context) (_ MessageType, _ io.Reader, err erro defer c.readMu.Unlock() if !c.msgReader.fin { - return 0, nil, xerrors.New("previous message not read to completion") + return 0, nil, errors.New("previous message not read to completion") } h, err := c.readLoop(ctx) @@ -308,7 +308,7 @@ func (c *Conn) reader(ctx context.Context) (_ MessageType, _ io.Reader, err erro } if h.opcode == opContinuation { - err := xerrors.New("received continuation frame without text or binary frame") + err := errors.New("received continuation frame without text or binary frame") c.writeError(StatusProtocolError, err) return 0, nil, err } @@ -357,10 +357,10 @@ func (mr *msgReader) setFrame(h header) { func (mr *msgReader) Read(p []byte) (n int, err error) { defer func() { - if xerrors.Is(err, io.ErrUnexpectedEOF) && mr.fin && mr.flate { + if errors.Is(err, io.ErrUnexpectedEOF) && mr.fin && mr.flate { err = io.EOF } - if xerrors.Is(err, io.EOF) { + if errors.Is(err, io.EOF) { err = io.EOF mr.putFlateReader() return @@ -397,7 +397,7 @@ func (mr *msgReader) read(p []byte) (int, error) { return 0, err } if h.opcode != opContinuation { - err := xerrors.New("received new data message without finishing the previous message") + err := errors.New("received new data message without finishing the previous message") mr.c.writeError(StatusProtocolError, err) return 0, err } @@ -448,7 +448,7 @@ func (lr *limitReader) reset(r io.Reader) { func (lr *limitReader) Read(p []byte) (int, error) { if lr.n <= 0 { - err := xerrors.Errorf("read limited at %v bytes", lr.limit.Load()) + err := fmt.Errorf("read limited at %v bytes", lr.limit.Load()) lr.c.writeError(StatusMessageTooBig, err) return 0, err } diff --git a/write.go b/write.go index b560b44cf25f79f999528b76a01b065ca50379e1..81b9141ae7e06aac325de7868ed4302bdfef4975 100644 --- a/write.go +++ b/write.go @@ -7,12 +7,13 @@ import ( "context" "crypto/rand" "encoding/binary" + "errors" + "fmt" "io" "sync" "time" "github.com/klauspost/compress/flate" - "golang.org/x/xerrors" "nhooyr.io/websocket/internal/errd" ) @@ -27,7 +28,7 @@ import ( func (c *Conn) Writer(ctx context.Context, typ MessageType) (io.WriteCloser, error) { w, err := c.writer(ctx, typ) if err != nil { - return nil, xerrors.Errorf("failed to get writer: %w", err) + return nil, fmt.Errorf("failed to get writer: %w", err) } return w, nil } @@ -41,7 +42,7 @@ func (c *Conn) Writer(ctx context.Context, typ MessageType) (io.WriteCloser, err func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { _, err := c.write(ctx, typ, p) if err != nil { - return xerrors.Errorf("failed to write msg: %w", err) + return fmt.Errorf("failed to write msg: %w", err) } return nil } @@ -53,14 +54,14 @@ type msgWriter struct { func (mw *msgWriter) Write(p []byte) (int, error) { if mw.closed { - return 0, xerrors.New("cannot use closed writer") + return 0, errors.New("cannot use closed writer") } return mw.mw.Write(p) } func (mw *msgWriter) Close() error { if mw.closed { - return xerrors.New("cannot use closed writer") + return errors.New("cannot use closed writer") } mw.closed = true return mw.mw.Close() @@ -182,7 +183,7 @@ func (mw *msgWriterState) Write(p []byte) (_ int, err error) { func (mw *msgWriterState) write(p []byte) (int, error) { n, err := mw.c.writeFrame(mw.ctx, false, mw.flate, mw.opcode, p) if err != nil { - return n, xerrors.Errorf("failed to write data frame: %w", err) + return n, fmt.Errorf("failed to write data frame: %w", err) } mw.opcode = opContinuation return n, nil @@ -197,7 +198,7 @@ func (mw *msgWriterState) Close() (err error) { _, err = mw.c.writeFrame(mw.ctx, true, mw.flate, mw.opcode, nil) if err != nil { - return xerrors.Errorf("failed to write fin frame: %w", err) + return fmt.Errorf("failed to write fin frame: %w", err) } if mw.flate && !mw.flateContextTakeover() { @@ -218,7 +219,7 @@ func (c *Conn) writeControl(ctx context.Context, opcode opcode, p []byte) error _, err := c.writeFrame(ctx, true, false, opcode, p) if err != nil { - return xerrors.Errorf("failed to write control frame %v: %w", opcode, err) + return fmt.Errorf("failed to write control frame %v: %w", opcode, err) } return nil } @@ -245,7 +246,7 @@ func (c *Conn) writeFrame(ctx context.Context, fin bool, flate bool, opcode opco c.writeHeader.masked = true _, err = io.ReadFull(rand.Reader, c.writeHeaderBuf[:4]) if err != nil { - return 0, xerrors.Errorf("failed to generate masking key: %w", err) + return 0, fmt.Errorf("failed to generate masking key: %w", err) } c.writeHeader.maskKey = binary.LittleEndian.Uint32(c.writeHeaderBuf[:]) } @@ -268,7 +269,7 @@ func (c *Conn) writeFrame(ctx context.Context, fin bool, flate bool, opcode opco if c.writeHeader.fin { err = c.bw.Flush() if err != nil { - return n, xerrors.Errorf("failed to flush: %w", err) + return n, fmt.Errorf("failed to flush: %w", err) } } diff --git a/ws_js.go b/ws_js.go index ecf3d78c1a78190a81e4c4f8a85114d42c884e7f..2b560ce87d93035a4e81e167a844d301ae4f1af4 100644 --- a/ws_js.go +++ b/ws_js.go @@ -3,6 +3,8 @@ package websocket // import "nhooyr.io/websocket" import ( "bytes" "context" + "errors" + "fmt" "io" "net/http" "reflect" @@ -10,8 +12,6 @@ import ( "sync" "syscall/js" - "golang.org/x/xerrors" - "nhooyr.io/websocket/internal/bpool" "nhooyr.io/websocket/internal/wsjs" "nhooyr.io/websocket/internal/xsync" @@ -45,7 +45,7 @@ func (c *Conn) close(err error, wasClean bool) { runtime.SetFinalizer(c, nil) if !wasClean { - err = xerrors.Errorf("unclean connection close: %w", err) + err = fmt.Errorf("unclean connection close: %w", err) } c.setCloseErr(err) c.closeWasClean = wasClean @@ -87,7 +87,7 @@ func (c *Conn) init() { }) runtime.SetFinalizer(c, func(c *Conn) { - c.setCloseErr(xerrors.New("connection garbage collected")) + c.setCloseErr(errors.New("connection garbage collected")) c.closeWithInternal() }) } @@ -100,15 +100,15 @@ func (c *Conn) closeWithInternal() { // The maximum time spent waiting is bounded by the context. func (c *Conn) Read(ctx context.Context) (MessageType, []byte, error) { if c.isReadClosed.Load() == 1 { - return 0, nil, xerrors.New("WebSocket connection read closed") + return 0, nil, errors.New("WebSocket connection read closed") } typ, p, err := c.read(ctx) if err != nil { - return 0, nil, xerrors.Errorf("failed to read: %w", err) + return 0, nil, fmt.Errorf("failed to read: %w", err) } if int64(len(p)) > c.msgReadLimit.Load() { - err := xerrors.Errorf("read limited at %v bytes", c.msgReadLimit.Load()) + err := fmt.Errorf("read limited at %v bytes", c.msgReadLimit.Load()) c.Close(StatusMessageTooBig, err.Error()) return 0, nil, err } @@ -166,7 +166,7 @@ func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { // to match the Go API. It can only error if the message type // is unexpected or the passed bytes contain invalid UTF-8 for // MessageText. - err := xerrors.Errorf("failed to write: %w", err) + err := fmt.Errorf("failed to write: %w", err) c.setCloseErr(err) c.closeWithInternal() return err @@ -184,7 +184,7 @@ func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) error { case MessageText: return c.ws.SendText(string(p)) default: - return xerrors.Errorf("unexpected message type: %v", typ) + return fmt.Errorf("unexpected message type: %v", typ) } } @@ -195,7 +195,7 @@ func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) error { func (c *Conn) Close(code StatusCode, reason string) error { err := c.exportedClose(code, reason) if err != nil { - return xerrors.Errorf("failed to close WebSocket: %w", err) + return fmt.Errorf("failed to close WebSocket: %w", err) } return nil } @@ -204,13 +204,13 @@ func (c *Conn) exportedClose(code StatusCode, reason string) error { c.closingMu.Lock() defer c.closingMu.Unlock() - ce := xerrors.Errorf("sent close: %w", CloseError{ + ce := fmt.Errorf("sent close: %w", CloseError{ Code: code, Reason: reason, }) if c.isClosed() { - return xerrors.Errorf("tried to close with %q but connection already closed: %w", ce, c.closeErr) + return fmt.Errorf("tried to close with %q but connection already closed: %w", ce, c.closeErr) } c.setCloseErr(ce) @@ -245,7 +245,7 @@ type DialOptions struct { func Dial(ctx context.Context, url string, opts *DialOptions) (*Conn, *http.Response, error) { c, resp, err := dial(ctx, url, opts) if err != nil { - return nil, nil, xerrors.Errorf("failed to WebSocket dial %q: %w", url, err) + return nil, nil, fmt.Errorf("failed to WebSocket dial %q: %w", url, err) } return c, resp, nil } @@ -318,25 +318,25 @@ type writer struct { func (w writer) Write(p []byte) (int, error) { if w.closed { - return 0, xerrors.New("cannot write to closed writer") + return 0, errors.New("cannot write to closed writer") } n, err := w.b.Write(p) if err != nil { - return n, xerrors.Errorf("failed to write message: %w", err) + return n, fmt.Errorf("failed to write message: %w", err) } return n, nil } func (w writer) Close() error { if w.closed { - return xerrors.New("cannot close closed writer") + return errors.New("cannot close closed writer") } w.closed = true defer bpool.Put(w.b) err := w.c.Write(w.ctx, w.typ, w.b.Bytes()) if err != nil { - return xerrors.Errorf("failed to close writer: %w", err) + return fmt.Errorf("failed to close writer: %w", err) } return nil } @@ -361,7 +361,7 @@ func (c *Conn) SetReadLimit(n int64) { func (c *Conn) setCloseErr(err error) { c.closeErrOnce.Do(func() { - c.closeErr = xerrors.Errorf("WebSocket closed: %w", err) + c.closeErr = fmt.Errorf("WebSocket closed: %w", err) }) } diff --git a/wsjson/wsjson.go b/wsjson/wsjson.go index e6f06a2fe9e3116f51a5c5fb8caac2c0acdaf4b8..99996a69a0ba23bda23fc8ed6f79d4c6da123224 100644 --- a/wsjson/wsjson.go +++ b/wsjson/wsjson.go @@ -4,8 +4,7 @@ package wsjson // import "nhooyr.io/websocket/wsjson" import ( "context" "encoding/json" - - "golang.org/x/xerrors" + "fmt" "nhooyr.io/websocket" "nhooyr.io/websocket/internal/bpool" @@ -28,7 +27,7 @@ func read(ctx context.Context, c *websocket.Conn, v interface{}) (err error) { if typ != websocket.MessageText { c.Close(websocket.StatusUnsupportedData, "expected text message") - return xerrors.Errorf("expected text message for JSON but got: %v", typ) + return fmt.Errorf("expected text message for JSON but got: %v", typ) } b := bpool.Get() @@ -42,7 +41,7 @@ func read(ctx context.Context, c *websocket.Conn, v interface{}) (err error) { err = json.Unmarshal(b.Bytes(), v) if err != nil { c.Close(websocket.StatusInvalidFramePayloadData, "failed to unmarshal JSON") - return xerrors.Errorf("failed to unmarshal JSON: %w", err) + return fmt.Errorf("failed to unmarshal JSON: %w", err) } return nil @@ -66,7 +65,7 @@ func write(ctx context.Context, c *websocket.Conn, v interface{}) (err error) { // a copy of the byte slice but Encoder does as it directly writes to w. err = json.NewEncoder(w).Encode(v) if err != nil { - return xerrors.Errorf("failed to marshal JSON: %w", err) + return fmt.Errorf("failed to marshal JSON: %w", err) } return w.Close() diff --git a/wspb/wspb.go b/wspb/wspb.go index 06ac3368fa1e8bd7f6aa8e5e79a1b6fd0ce135a7..e43042d5452e53accce7082dba5c6950a3386579 100644 --- a/wspb/wspb.go +++ b/wspb/wspb.go @@ -4,9 +4,9 @@ package wspb // import "nhooyr.io/websocket/wspb" import ( "bytes" "context" + "fmt" "github.com/golang/protobuf/proto" - "golang.org/x/xerrors" "nhooyr.io/websocket" "nhooyr.io/websocket/internal/bpool" @@ -29,7 +29,7 @@ func read(ctx context.Context, c *websocket.Conn, v proto.Message) (err error) { if typ != websocket.MessageBinary { c.Close(websocket.StatusUnsupportedData, "expected binary message") - return xerrors.Errorf("expected binary message for protobuf but got: %v", typ) + return fmt.Errorf("expected binary message for protobuf but got: %v", typ) } b := bpool.Get() @@ -43,7 +43,7 @@ func read(ctx context.Context, c *websocket.Conn, v proto.Message) (err error) { err = proto.Unmarshal(b.Bytes(), v) if err != nil { c.Close(websocket.StatusInvalidFramePayloadData, "failed to unmarshal protobuf") - return xerrors.Errorf("failed to unmarshal protobuf: %w", err) + return fmt.Errorf("failed to unmarshal protobuf: %w", err) } return nil @@ -66,7 +66,7 @@ func write(ctx context.Context, c *websocket.Conn, v proto.Message) (err error) err = pb.Marshal(v) if err != nil { - return xerrors.Errorf("failed to marshal protobuf: %w", err) + return fmt.Errorf("failed to marshal protobuf: %w", err) } return c.Write(ctx, websocket.MessageBinary, pb.Bytes())