func wsDial(addr string, config *websocket.Config) (*websocket.Conn, error) { rwc, err := net.Dial("tcp", addr) if err != nil { return nil, err } return websocket.NewClient(config, rwc) }
func TestWebSocketConnection(t *testing.T) { srvAddr := "localhost:8080" config, err := wsConnSetup(srvAddr) if err != nil { t.Errorf("Could not find TCP address:", err.Error()) } client, err := net.Dial("tcp", srvAddr) if err != nil { t.Fatal("dialing", err) } conn, err := websocket.NewClient(config, client) if err != nil { t.Errorf("WebSocket handshake error: %v", err) return } //msg := []byte("hello, world\n") msg := []byte(`[{ "name": "user:join", "args": {"id": -1} }]`) if _, err := conn.Write(msg); err != nil { t.Errorf("Write: %v", err) } conn.Close() }
func BenchmarkWebSocketConnection(b *testing.B) { b.StopTimer() if !startedMain { go main() startedMain = true time.Sleep(100) } srvAddr := "localhost:8080" config, _ := wsConnSetup(srvAddr) b.StartTimer() for i := 0; i < b.N; i++ { client, _ := net.Dial("tcp", srvAddr) conn, _ := websocket.NewClient(config, client) msg := []byte(`[{ "name": "user:new", "args": {"id": -1} }]`) conn.Write(msg) conn.Close() } }
func TestWormsServerConnect(t *testing.T) { once.Do(startServer) client, err := net.Dial("tcp", serverAddr) if err != nil { t.Fatal("dialing", err) } conn, err := websocket.NewClient(newConfig(t, "/worms"), client) if err != nil { t.Errorf("WebSocket handshake error: %v", err) return } defer conn.Close() if err := websocket.JSON.Send(conn, Packet{Command: "HELLO"}); err != nil { t.Errorf("Write: %v", err) } var actual_msg Packet timer := time.AfterFunc(TICK*2*time.Millisecond, func() { t.Errorf("Timed out waiting for a reply") }) if err := websocket.JSON.Receive(conn, &actual_msg); err != nil { t.Errorf("Read: %v", err) } timer.Stop() switch actual_msg.Command { case "MOVE", "KILL", "HELLO": default: t.Errorf("Unexpected reply", actual_msg) } }
func DialConfigTimeout(config *websocket.Config, timeout time.Duration) (ws *websocket.Conn, err error) { var client net.Conn if config.Location == nil { return nil, &websocket.DialError{config, websocket.ErrBadWebSocketLocation} } if config.Origin == nil { return nil, &websocket.DialError{config, websocket.ErrBadWebSocketOrigin} } switch config.Location.Scheme { case "ws": client, err = net.DialTimeout("tcp", config.Location.Host, timeout) // tls.go doesn't support DialTimeout so we don't support it default: err = websocket.ErrBadScheme } if err != nil { goto Error } ws, err = websocket.NewClient(config, client) if err != nil { goto Error } return Error: return nil, &websocket.DialError{config, err} }
func TestGetContainersAttachWebsocket(t *testing.T) { runCmd := exec.Command(dockerBinary, "run", "-dit", "busybox", "cat") out, _, err := runCommandWithOutput(runCmd) if err != nil { t.Fatalf(out, err) } defer deleteAllContainers() rwc, err := sockConn(time.Duration(10 * time.Second)) if err != nil { t.Fatal(err) } cleanedContainerID := stripTrailingCharacters(out) config, err := websocket.NewConfig( "/containers/"+cleanedContainerID+"/attach/ws?stream=1&stdin=1&stdout=1&stderr=1", "http://localhost", ) if err != nil { t.Fatal(err) } ws, err := websocket.NewClient(config, rwc) if err != nil { t.Fatal(err) } defer ws.Close() expected := []byte("hello") actual := make([]byte, len(expected)) outChan := make(chan string) go func() { if _, err := ws.Read(actual); err != nil { t.Fatal(err) } outChan <- "done" }() inChan := make(chan string) go func() { if _, err := ws.Write(expected); err != nil { t.Fatal(err) } inChan <- "done" }() <-inChan <-outChan if !bytes.Equal(expected, actual) { t.Fatal("Expected output on websocket to match input") } logDone("container attach websocket - can echo input via cat") }
func (c *WebsocketClient) dialTimeout(config *websocket.Config, timeout uint) (ws *websocket.Conn, err error) { c.logger.Debug("ConnectOnce:websocket.DialConfig:call") defer c.logger.Debug("ConnectOnce:websocket.DialConfig:return") // websocket.Dial() does not handle timeouts, so we use lower-level net package // to create connection with timeout, then create ws client with the net connection. if config.Location == nil { return nil, websocket.ErrBadWebSocketLocation } if config.Origin == nil { return nil, websocket.ErrBadWebSocketOrigin } var conn net.Conn switch config.Location.Scheme { case "ws": conn, err = net.DialTimeout("tcp", config.Location.Host, time.Duration(timeout)*time.Second) case "wss": dialer := &net.Dialer{ Timeout: time.Duration(timeout) * time.Second, } if config.Location.Host == "localhost:8443" { // Test uses mock ws server which uses self-signed cert which causes Go to throw // an error like "x509: certificate signed by unknown authority". This disables // the cert verification for testing. config.TlsConfig = &tls.Config{ InsecureSkipVerify: true, } } conn, err = tls.DialWithDialer(dialer, "tcp", config.Location.Host, config.TlsConfig) default: err = websocket.ErrBadScheme } if err != nil { return nil, &websocket.DialError{config, err} } ws, err = websocket.NewClient(config, conn) if err != nil { return nil, err } return ws, nil }
// BtcdWS opens a websocket connection to a btcd instance. func BtcdWS(certificates []byte) (*websocket.Conn, error) { url := fmt.Sprintf("wss://%s/ws", cfg.RPCConnect) config, err := websocket.NewConfig(url, "https://localhost/") if err != nil { return nil, err } // btcd uses a self-signed TLS certifiate which is used as the CA. pool := x509.NewCertPool() pool.AppendCertsFromPEM(certificates) config.TlsConfig = &tls.Config{ RootCAs: pool, MinVersion: tls.VersionTLS12, } // btcd requires basic authorization, so set the Authorization header. login := cfg.Username + ":" + cfg.Password auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) config.Header.Add("Authorization", auth) // Dial connection. var ws *websocket.Conn var cerr error if cfg.Proxy != "" { proxy := &socks.Proxy{ Addr: cfg.Proxy, Username: cfg.ProxyUser, Password: cfg.ProxyPass, } conn, err := proxy.Dial("tcp", cfg.RPCConnect) if err != nil { return nil, err } tlsConn := tls.Client(conn, config.TlsConfig) ws, cerr = websocket.NewClient(config, tlsConn) } else { ws, cerr = websocket.DialConfig(config) } if cerr != nil { return nil, cerr } return ws, nil }
func addWsClient(t *testing.T, roomID string, clientID string) *websocket.Conn { c, err := net.Dial("tcp", serverAddr) if err != nil { t.Fatalf("net.Dial(tcp, %q) got error: %s, want nil", serverAddr, err.Error()) } config := newConfig(t, "/ws") conn, err := websocket.NewClient(config, c) if err != nil { t.Fatalf("websocket.NewClient(%v, %v) got error: %s, want nil", config, c, err.Error()) } // Registers the client. m := wsClientMsg{ Cmd: "register", ClientID: clientID, RoomID: roomID, } write(t, conn, m) return conn }
func BenchmarkWebSocketConnection(b *testing.B) { srvAddr := "localhost:8080" config, _ := wsConnSetup(srvAddr) for i := 0; i < b.N; i++ { client, _ := net.Dial("tcp", srvAddr) conn, _ := websocket.NewClient(config, client) //msg := []byte("hello, world\n") msg := []byte(`[{ "name": "user:join", "args": {"id": -1} }]`) conn.Write(msg) conn.Close() } }
func (s *S) TestHTTPWebsocket(c *C) { done := make(chan struct{}) srv := httptest.NewServer( websocket.Handler(func(conn *websocket.Conn) { _, err := conn.Write([]byte("1")) c.Assert(err, IsNil) res := make([]byte, 1) _, err = conn.Read(res) c.Assert(err, IsNil) c.Assert(res[0], Equals, byte('2')) close(done) }), ) l, discoverd, err := newHTTPListener(nil) c.Assert(err, IsNil) defer l.Close() discoverd.Register("test", srv.Listener.Addr().String()) defer discoverd.UnregisterAll() addHTTPRoute(c, l) conn, err := net.Dial("tcp", l.Addr) c.Assert(err, IsNil) defer conn.Close() conf, err := websocket.NewConfig("ws://example.com", "http://example.net") c.Assert(err, IsNil) wc, err := websocket.NewClient(conf, conn) c.Assert(err, IsNil) res := make([]byte, 1) _, err = wc.Read(res) c.Assert(err, IsNil) c.Assert(res[0], Equals, byte('1')) _, err = wc.Write([]byte("2")) c.Assert(err, IsNil) }
func connect() { var origin = "http://localhost:8000/" config, err := websocket.NewConfig(slackBotClient.socketURL, origin) if err != nil { log.Fatal(err) } var client net.Conn if config.Location == nil { log.Fatal(websocket.DialError{config, websocket.ErrBadWebSocketLocation}) } if config.Origin == nil { log.Fatal(websocket.DialError{config, websocket.ErrBadWebSocketOrigin}) } switch config.Location.Scheme { case "ws": client, err = net.Dial("tcp", config.Location.Host) case "wss": client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig) default: err = websocket.ErrBadScheme } pp.Println(config) pp.Println(client) if err != nil { log.Fatal(websocket.DialError{config, err}) } var wsConn *websocket.Conn wsConn, err = websocket.NewClient(config, client) if err != nil { log.Fatal(websocket.DialError{config, err}) } pp.Println(wsConn) return // wsOpen, err := websocket.Dial(slackBotClient.socketURL, "", origin) // if err != nil { // log.Fatal(err) // } // // message := []byte("hello, world!") // _, err = wsOpen.Write(message) // if err != nil { // log.Fatal(err) // } // fmt.Printf("Send: %s\n", message) // // var msg = make([]byte, 512) // _, err = wsOpen.Read(msg) // if err != nil { // log.Fatal(err) // } // fmt.Printf("Receive: %s\n", msg) }
func (s *DockerSuite) TestGetContainersAttachWebsocket(c *check.C) { runCmd := exec.Command(dockerBinary, "run", "-dit", "busybox", "cat") out, _, err := runCommandWithOutput(runCmd) if err != nil { c.Fatalf(out, err) } rwc, err := sockConn(time.Duration(10 * time.Second)) if err != nil { c.Fatal(err) } cleanedContainerID := strings.TrimSpace(out) config, err := websocket.NewConfig( "/containers/"+cleanedContainerID+"/attach/ws?stream=1&stdin=1&stdout=1&stderr=1", "http://localhost", ) if err != nil { c.Fatal(err) } ws, err := websocket.NewClient(config, rwc) if err != nil { c.Fatal(err) } defer ws.Close() expected := []byte("hello") actual := make([]byte, len(expected)) outChan := make(chan error) go func() { _, err := ws.Read(actual) outChan <- err close(outChan) }() inChan := make(chan error) go func() { _, err := ws.Write(expected) inChan <- err close(inChan) }() select { case err := <-inChan: if err != nil { c.Fatal(err) } case <-time.After(5 * time.Second): c.Fatal("Timeout writing to ws") } select { case err := <-outChan: if err != nil { c.Fatal(err) } case <-time.After(5 * time.Second): c.Fatal("Timeout reading from ws") } if !bytes.Equal(expected, actual) { c.Fatal("Expected output on websocket to match input") } }
// ListenAndUpdate opens a websocket connection to a btcwallet // instance and initiates requests to fill the GUI with relevant // information. func ListenAndUpdate(certificates []byte, c chan error) { // Start each updater func in a goroutine. Use a sync.Once to // ensure there are no duplicate updater functions running. updateOnce.Do(func() { for _, f := range updateFuncs { go f() } }) // Connect to websocket. url := fmt.Sprintf("wss://%s/frontend", cfg.Connect) config, err := websocket.NewConfig(url, "https://localhost/") if err != nil { log.Printf("[ERR] cannot create websocket config: %v", err) c <- ErrConnectionRefused return } pool := x509.NewCertPool() pool.AppendCertsFromPEM(certificates) config.TlsConfig = &tls.Config{ RootCAs: pool, MinVersion: tls.VersionTLS12, } // btcwallet requires basic authorization, so we use a custom config // with the Authorization header set. login := cfg.Username + ":" + cfg.Password auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) config.Header.Add("Authorization", auth) // Attempt to connect to running btcwallet instance. Bail if it fails. var ws *websocket.Conn var cerr error if cfg.Proxy != "" { proxy := &socks.Proxy{ Addr: cfg.Proxy, Username: cfg.ProxyUser, Password: cfg.ProxyPass, } conn, err := proxy.Dial("tcp", cfg.Connect) if err != nil { log.Printf("Error connecting to proxy: %v", err) c <- ErrConnectionRefused return } tlsConn := tls.Client(conn, config.TlsConfig) ws, cerr = websocket.NewClient(config, tlsConn) } else { ws, cerr = websocket.DialConfig(config) } if cerr != nil { log.Printf("[ERR] Cannot create websocket client: %v", cerr) c <- ErrConnectionRefused return } c <- nil // Buffered channel for replies and notifications from btcwallet. replies := make(chan []byte, 100) go func() { for { // Receive message from wallet var msg []byte err := websocket.Message.Receive(ws, &msg) if err != nil { close(replies) return } replies <- msg } }() for _, f := range walletReqFuncs { go f(ws) } for { select { case r, ok := <-replies: if !ok { // btcwallet connection lost. c <- ErrConnectionLost return } // Handle message here. go ProcessBtcwalletMessage(r) case <-triggers.newAddr: go cmdGetNewAddress(ws) case params := <-triggers.newWallet: go cmdCreateEncryptedWallet(ws, params) case <-triggers.lockWallet: go cmdWalletLock(ws) case params := <-triggers.unlockWallet: go cmdWalletPassphrase(ws, params) case pairs := <-triggers.sendTx: go cmdSendMany(ws, pairs) case fee := <-triggers.setTxFee: go cmdSetTxFee(ws, fee) } } }