rpc: add HTTP status code to handshake error

This makes it easier to debug failing connections.
This commit is contained in:
Felix Lange 2019-07-19 16:50:37 +02:00
parent bbfe6f9c17
commit 80f3a0647f
2 changed files with 23 additions and 3 deletions

View file

@ -111,6 +111,19 @@ func wsHandshakeValidator(allowedOrigins []string) func(*http.Request) bool {
return f return f
} }
type wsHandshakeError struct {
err error
status string
}
func (e wsHandshakeError) Error() string {
s := e.err.Error()
if e.status != "" {
s += " (HTTP status " + e.status + ")"
}
return s
}
// DialWebsocket creates a new RPC client that communicates with a JSON-RPC server // DialWebsocket creates a new RPC client that communicates with a JSON-RPC server
// that is listening on the given endpoint. // that is listening on the given endpoint.
// //
@ -127,9 +140,13 @@ func DialWebsocket(ctx context.Context, endpoint, origin string) (*Client, error
WriteBufferPool: wsBufferPool, WriteBufferPool: wsBufferPool,
} }
return newClient(ctx, func(ctx context.Context) (ServerCodec, error) { return newClient(ctx, func(ctx context.Context) (ServerCodec, error) {
conn, _, err := dialer.DialContext(ctx, endpoint, header) conn, resp, err := dialer.DialContext(ctx, endpoint, header)
if err != nil { if err != nil {
return nil, err hErr := wsHandshakeError{err: err}
if resp != nil {
hErr.status = resp.Status
}
return nil, hErr
} }
return newWebsocketCodec(conn), nil return newWebsocketCodec(conn), nil
}) })

View file

@ -21,6 +21,7 @@ import (
"net" "net"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"reflect"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -63,10 +64,12 @@ func TestWebsocketOriginCheck(t *testing.T) {
client.Close() client.Close()
t.Fatal("no error for wrong origin") t.Fatal("no error for wrong origin")
} }
if err != websocket.ErrBadHandshake { wantErr := wsHandshakeError{websocket.ErrBadHandshake, "403 Forbidden"}
if !reflect.DeepEqual(err, wantErr) {
t.Fatalf("wrong error for wrong origin: %q", err) t.Fatalf("wrong error for wrong origin: %q", err)
} }
// Connections without origin header should work.
client, err = DialWebsocket(context.Background(), wsURL, "") client, err = DialWebsocket(context.Background(), wsURL, "")
if err != nil { if err != nil {
t.Fatal("error for empty origin") t.Fatal("error for empty origin")