func TestEcho(t *testing.T) { http.Handle("/echo", websocket.Handler(echoServer)) once.Do(startCherryServer) client, err := net.Dial("tcp", serverAddr) if err != nil { t.Fatal("dialing", err) } conn, err := websocket.NewClient(newConfig(t, "/echo"), client) if err != nil { t.Errorf("WebSocket handshake error: %v", err) return } msg := []byte("hello, world\n") if _, err := conn.Write(msg); err != nil { t.Errorf("Write: %v", err) } var actual_msg = make([]byte, 512) n, err := conn.Read(actual_msg) if err != nil { t.Errorf("Read: %v", err) } actual_msg = actual_msg[0:n] if !bytes.Equal(msg, actual_msg) { t.Errorf("Echo: expected %q got %q", msg, actual_msg) } conn.Close() }
func (st *serverTester) websocket(rp requestParam) (*serverResponse, error) { urlstring := st.url + "/echo" config, err := websocket.NewConfig(urlstring, st.url) if err != nil { st.t.Fatalf("websocket.NewConfig(%q, %q) returned error: %v", urlstring, st.url, err) } config.Header.Add("Test-Case", rp.name) for _, h := range rp.header { config.Header.Add(h.Name, h.Value) } ws, err := websocket.NewClient(config, st.conn) if err != nil { st.t.Fatalf("Error creating websocket client: %v", err) } if _, err := ws.Write(rp.body); err != nil { st.t.Fatalf("ws.Write() returned error: %v", err) } msg := make([]byte, 1024) var n int if n, err = ws.Read(msg); err != nil { st.t.Fatalf("ws.Read() returned error: %v", err) } res := &serverResponse{ body: msg[:n], } return res, nil }
func (s *S) TestServeHTTPWebSocket(c *check.C) { var servers []*httptest.Server for i := 0; i < 2; i++ { msg := fmt.Sprintf("server-%d", i) srv := httptest.NewServer(websocket.Handler(func(conn *websocket.Conn) { conn.Write([]byte(msg + conn.Request().URL.Path)) buf := make([]byte, 5) conn.Read(buf) conn.Write(buf) })) defer srv.Close() servers = append(servers, srv) } var err error _, err = s.redis.Do("RPUSH", "frontend:myfrontend.com", "myfrontend", servers[0].URL, servers[1].URL) c.Assert(err, check.IsNil) router := Router{} err = router.Init() c.Assert(err, check.IsNil) proxyServer := httptest.NewServer(&router) defer proxyServer.Close() dialWS := func() *websocket.Conn { config, err := websocket.NewConfig("ws://myfrontend.com", "ws://localhost/") c.Assert(err, check.IsNil) url, _ := url.Parse(proxyServer.URL) client, err := net.Dial("tcp", url.Host) c.Assert(err, check.IsNil) conn, err := websocket.NewClient(config, client) c.Assert(err, check.IsNil) return conn } msgBuf := make([]byte, 100) conn := dialWS() defer conn.Close() n, err := conn.Read(msgBuf) c.Assert(err, check.IsNil) c.Assert(n, check.Equals, 9) c.Assert(string(msgBuf[:n]), check.Equals, "server-0/") n, err = conn.Write([]byte("12345")) c.Assert(err, check.IsNil) c.Assert(n, check.Equals, 5) n, err = conn.Read(msgBuf) c.Assert(err, check.IsNil) c.Assert(n, check.Equals, 5) c.Assert(string(msgBuf[:n]), check.Equals, "12345") conn = dialWS() defer conn.Close() n, err = conn.Read(msgBuf) c.Assert(err, check.IsNil) c.Assert(n, check.Equals, 9) c.Assert(string(msgBuf[:n]), check.Equals, "server-1/") n, err = conn.Write([]byte("12345")) c.Assert(err, check.IsNil) c.Assert(n, check.Equals, 5) n, err = conn.Read(msgBuf) c.Assert(err, check.IsNil) c.Assert(n, check.Equals, 5) c.Assert(string(msgBuf[:n]), check.Equals, "12345") }
func (c *Client) proxyWebsocket(config *websocket.Config, proxy string) (*websocket.Conn, error) { u, err := url.Parse(proxy) if err != nil { return nil, err } host := u.Host if !strings.Contains(host, ":") { host += ":443" } conn, err := net.DialTimeout("tcp", u.Host, 3*time.Second) if err != nil { return nil, err } if _, err = conn.Write([]byte(fmt.Sprintf("CONNECT %s:443 HTTP/1.1\r\n", c.Host))); err != nil { return nil, err } if _, err = conn.Write([]byte(fmt.Sprintf("Host: %s:443\r\n", c.Host))); err != nil { return nil, err } if auth := u.User; auth != nil { enc := base64.StdEncoding.EncodeToString([]byte(auth.String())) if _, err = conn.Write([]byte(fmt.Sprintf("Proxy-Authorization: Basic %s\r\n", enc))); err != nil { return nil, err } } if _, err = conn.Write([]byte("Proxy-Connection: Keep-Alive\r\n\r\n")); err != nil { return nil, err } data, err := bufio.NewReader(conn).ReadString('\n') if err != nil { return nil, err } // need an http 200 response if !strings.Contains(string(data), " 200 ") { return nil, fmt.Errorf("proxy error: %s", strings.TrimSpace(string(data))) } return websocket.NewClient(config, tls.Client(conn, config.TlsConfig)) }
func (h DockerHandler) GetWebSocket(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error) { client, err := net.Dial("unix", h.dockerEndpoint) if err != nil { helpers.ErrorLog("DOCKER", fmt.Sprintf("Following error occured when trying to make request to Docker endpoint %s : %s", h.dockerEndpoint, err.Error())) return nil, err } config := &websocket.Config{} config.Version = websocket.ProtocolVersionHybi13 config.Location = r.URL config.Origin = r.URL config.Header = r.Header return websocket.NewClient(config, client) }
// dialSocketListener opens a WebSocket client connection to pl with config. // config.Location, config.Origin, and config.Version must be set. func dialSocketListener(pl *pipeListener, config *websocket.Config) ( conn *websocket.Conn, err error) { socket, err := pl.Dial("", "") if err != nil { return nil, err } if conn, err = websocket.NewClient(config, socket); err != nil { socket.Close() return nil, err } return conn, nil }
func (w WS) Select(netcon net.Conn, url string) (*websocket.Conn, error) { conf, err := websocket.NewConfig(url, url) if err != nil { return nil, err } wcon, err := websocket.NewClient(conf, netcon) if err != nil { return nil, err } return wcon, nil }
func (s *DockerSuite) TestGetContainersAttachWebsocket(c *check.C) { testRequires(c, DaemonIsLinux) out, _ := dockerCmd(c, "run", "-dit", "busybox", "cat") rwc, err := sockConn(time.Duration(10*time.Second), "") c.Assert(err, checker.IsNil) cleanedContainerID := strings.TrimSpace(out) config, err := websocket.NewConfig( "/containers/"+cleanedContainerID+"/attach/ws?stream=1&stdin=1&stdout=1&stderr=1", "http://localhost", ) c.Assert(err, checker.IsNil) ws, err := websocket.NewClient(config, rwc) c.Assert(err, checker.IsNil) defer ws.Close() expected := []byte("hello") actual := make([]byte, len(expected)) outChan := make(chan error) go func() { _, err := io.ReadFull(ws, actual) outChan <- err close(outChan) }() inChan := make(chan error) go func() { _, err := ws.Write(expected) inChan <- err close(inChan) }() select { case err := <-inChan: c.Assert(err, checker.IsNil) case <-time.After(5 * time.Second): c.Fatal("Timeout writing to ws") } select { case err := <-outChan: c.Assert(err, checker.IsNil) case <-time.After(5 * time.Second): c.Fatal("Timeout reading from ws") } c.Assert(actual, checker.DeepEquals, expected, check.Commentf("Websocket didn't return the expected data")) }
// Connects to the tab/process for sending/recv'ing debug events func wsConnection(addr, url string) *websocket.Conn { conn, err := net.Dial("tcp", addr) if err != nil { log.Fatal("error dialing ChromeTarget websocket: ", err) } config, errConfig := websocket.NewConfig(url, "http://localhost") if errConfig != nil { log.Fatalf("error building websocket config: addr: %s url: %s %v\n", addr, url, err) } client, errWS := websocket.NewClient(config, conn) if errWS != nil { log.Fatalf("error during websocket handshake: %v\n", errWS) } return client }
func newClient() (*websocket.Conn, error) { //todo L: client, err := net.Dial("tcp", cfg.AgentAddr()) if err != nil { log.Warning("not connected to agent server, try again ...") time.Sleep(1 * time.Second) goto L } conn, err := websocket.NewClient(newConfig_("/"), client) if err != nil { log.Errorf("WebSocket handshake error: %v", err) return nil, err } return conn, nil }
func TestCount(t *testing.T) { http.Handle("/count", websocket.Handler(countServer)) once.Do(startCherryServer) // websocket.Dial() client, err := net.Dial("tcp", serverAddr) if err != nil { t.Fatal("dialing", err) } conn, err := websocket.NewClient(newConfig(t, "/count"), client) if err != nil { t.Errorf("WebSocket handshake error: %v", err) return } var count Count count.S = "hello" if err := websocket.JSON.Send(conn, count); err != nil { t.Errorf("Write: %v", err) } if err := websocket.JSON.Receive(conn, &count); err != nil { t.Errorf("Read: %v", err) } if count.N != 1 { t.Errorf("count: expected %d got %d", 1, count.N) } if count.S != "hello" { t.Errorf("count: expected %q got %q", "hello", count.S) } if err := websocket.JSON.Send(conn, count); err != nil { t.Errorf("Write: %v", err) } if err := websocket.JSON.Receive(conn, &count); err != nil { t.Errorf("Read: %v", err) } if count.N != 2 { t.Errorf("count: expected %d got %d", 2, count.N) } if count.S != "hellohello" { t.Errorf("count: expected %q got %q", "hellohello", count.S) } conn.Close() }
func newWSConn(originURL, user, pass string) (*wsConn, error) { v := url.Values{} v.Set("login", user) v.Set("password", pass) params := v.Encode() wsURL := strings.Replace(originURL, "http", "ws", 1) + "?" + params wsConfig, err := websocket.NewConfig(wsURL, originURL) if err != nil { return nil, err } wsConfig.TlsConfig = &tls.Config{RootCAs: rootCA} var wsc *websocket.Conn req := http.Request{ URL: &url.URL{}, } proxyURL, err := getProxy(&req) if err != nil { return nil, err } if proxyURL == nil { wsc, err = websocket.DialConfig(wsConfig) if err != nil { return nil, err } } else { conn, err := httpConnect(proxyURL.Host, wsConfig) if err != nil { return nil, err } if wsConfig.Location.Scheme == "wss" { conn = tls.Client(conn, wsConfig.TlsConfig) } wsc, err = websocket.NewClient(wsConfig, conn) if err != nil { return nil, err } } return &wsConn{conn: wsc}, nil }
func NewClient(addr string, m ClientModel, out chan string) (*Client, error) { L: client, err := net.Dial("tcp", addr) if err != nil { log.Warningf("not connected to %+v, try again ...", addr) time.Sleep(1 * time.Second) goto L } conn, err := websocket.NewClient(newConfig("/"), client) if err != nil { log.Errorf("WebSocket handshake error: %v", err) return nil, err } rwc := NewWsReadWriter(conn) return &Client{ ReadWriteCloser: rwc, ClientModel: m, send: make(chan string, 10), ctrl: out, }, 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 Fuzz(data []byte) int { cfg, err := websocket.NewConfig("http://golang.org/", "http://golang.org/") if err != nil { panic(err) } // Header: http.Header{}, conn := &Conn{data, false} ws, err := websocket.NewClient(cfg, conn) if err != nil { return 0 } ws.Write([]byte("abc")) var buf [16]byte ws.Read(buf[:]) ws.Read(buf[:]) ws.Close() if !conn.closed { panic("conn is not closed") } return 1 }
func websocketProxyDial(urlString, origin string) (ws *websocket.Conn, err error) { if os.Getenv("HTTP_PROXY") == "" { return websocket.Dial(urlString, "", origin) } purl, err := url.Parse(os.Getenv("HTTP_PROXY")) if err != nil { return nil, err } config, err := websocket.NewConfig(urlString, origin) if err != nil { return nil, err } client, err := websocketHTTPConnect(purl.Host, urlString) if err != nil { return nil, err } switch config.Location.Scheme { case "ws": case "wss": tlsClient := tls.Client(client, &tls.Config{ ServerName: strings.Split(config.Location.Host, ":")[0], }) err := tlsClient.Handshake() if err != nil { tlsClient.Close() return nil, err } client = tlsClient default: return nil, errors.New("invalid websocket schema") } return websocket.NewClient(config, client) }
func connect(localip string) { origin := "http://192.168.1.150/" url := "ws://192.168.1.150:8080/ws" //ws, err = websocket.Dial(url, "", origin) config, err := websocket.NewConfig(url, origin) if err != nil { log.Println(err) return } localaddr := &net.TCPAddr{IP: net.ParseIP(localip)} remoteaddr := &net.TCPAddr{IP: net.ParseIP("192.168.1.150"), Port: 8080} client, err := net.DialTCP("tcp4", localaddr, remoteaddr) if err != nil { log.Println(err) return } _, err = websocket.NewClient(config, client) if err != nil { log.Println(err) } time.Sleep(time.Second * 100) return }
func TestServer1(t *testing.T) { once.Do(startServer1) // websocket.Dial() client, err := net.Dial("tcp", serverAddr) if err != nil { t.Fatal("dialing", err) } log.Info("t=%v", t) conn, err := websocket.NewClient(newConfig_("/agent"), client) if err != nil { t.Errorf("WebSocket handshake error: %v", err) return } for i := 0; i < 10; i++ { msg := []byte("hello, world") fw.PrintType(msg, "msg") msg = append(msg, byte(i)) // append(msg, []byte("\n")) if _, err := conn.Write(msg); err != nil { t.Errorf("Write: %v", err) } var actual_msg = make([]byte, 512) n, err := conn.Read(actual_msg) if err != nil { t.Errorf("Read: %v", err) } actual_msg = actual_msg[0:n] if !bytes.Equal(msg, actual_msg) { t.Logf("Test: send %q got %q", msg, actual_msg) } } conn.Close() }
func sendWebsocketRequest(serverAddr, path, data string, c *C) (received string, err error) { client, err := net.DialTimeout("tcp", serverAddr, dialTimeout) if err != nil { return "", err } config := newWebsocketConfig(serverAddr, path) conn, err := websocket.NewClient(config, client) if err != nil { return "", err } defer conn.Close() if _, err := conn.Write([]byte(data)); err != nil { return "", err } var msg = make([]byte, 512) var n int n, err = conn.Read(msg) if err != nil { return "", err } received = string(msg[:n]) return received, nil }
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") } }
func (s *S) TestHTTPWebsocket(c *C) { done := make(chan struct{}) h := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { if req.URL.Path != "/websocket" { w.Write([]byte("not a websocket upgrade\n")) return } 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')) done <- struct{}{} }).ServeHTTP(w, req) }) srv := httptest.NewServer(h) defer srv.Close() l := s.newHTTPListener(c) defer l.Close() addHTTPRoute(c, l) discoverdRegisterHTTP(c, l, srv.Listener.Addr().String()) tests := []struct { afterKeepAlive bool }{ {afterKeepAlive: false}, {afterKeepAlive: true}, // ensure that upgrade still works on reused conn } for _, test := range tests { conn, err := net.Dial("tcp", l.Addr) c.Assert(err, IsNil) defer conn.Close() if test.afterKeepAlive { req, err := http.NewRequest("GET", "http://example.com", nil) c.Assert(err, IsNil) err = req.Write(conn) c.Assert(err, IsNil) res, err := http.ReadResponse(bufio.NewReader(conn), req) c.Assert(err, IsNil) data, err := ioutil.ReadAll(res.Body) c.Assert(err, IsNil) res.Body.Close() c.Assert(res.StatusCode, Equals, 200) c.Assert(string(data), Equals, "not a websocket upgrade\n") } conf, err := websocket.NewConfig("ws://example.com/websocket", "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) <-done } }
func (d *dialer) Dial() (mangos.Pipe, error) { var w *wsPipe pname := d.proto.PeerName() + ".sp.nanomsg.org" // We have to supply an origin because Go's websocket // implementation seems to require it. We fake a garbage one. // Perhaps we should allow applications to fake this out. d.origin = "x://" config, err := websocket.NewConfig(d.addr, d.origin) if err != nil { return nil, err } config.Protocol = append([]string{}, pname) if v, ok := d.opts[mangos.OptionTlsConfig]; ok { config.TlsConfig = v.(*tls.Config) } host := config.Location.Host if strings.Index(host, ":") < 0 { if d.iswss { host = host + ":443" } else { host = host + ":80" } } taddr, err := net.ResolveTCPAddr("tcp", host) if err != nil { return nil, err } tconn, err := net.DialTCP("tcp", nil, taddr) if err != nil { return nil, err } laddr := tconn.LocalAddr() if v, ok := d.opts[mangos.OptionNoDelay]; ok { if err := tconn.SetNoDelay(v.(bool)); err != nil { tconn.Close() return nil, err } } if v, ok := d.opts[mangos.OptionKeepAlive]; ok { if err := tconn.SetKeepAlive(v.(bool)); err != nil { tconn.Close() return nil, err } } w = &wsPipe{proto: d.proto, addr: d.addr, open: true} w.props = make(map[string]interface{}) var conn net.Conn if d.iswss { tlsconn := tls.Client(tconn, config.TlsConfig) w.props[mangos.PropTlsConnState] = tlsconn.ConnectionState() w.iswss = true conn = tlsconn } else { conn = tconn } if w.ws, err = websocket.NewClient(config, conn); err != nil { conn.Close() return nil, err } w.props[mangos.PropLocalAddr] = laddr w.props[mangos.PropRemoteAddr] = w.ws.RemoteAddr() w.wg.Add(1) return w, nil }
// getRoute is a utility function for making the web request to a route. // Protocol is one of http, https, ws, or wss. If the protocol is https or wss, // then getRoute will make a secure transport client with InsecureSkipVerify: // true. If the protocol is http or ws, then getRoute does an unencrypted HTTP // client request. If the protocol is ws or wss, then getRoute will upgrade the // connection to websockets and then send expectedResponse *to* the route, with // the expectation that the route will echo back what it receives. Note that // getRoute returns only the first len(expectedResponse) bytes of the actual // response. func getRoute(routerUrl string, hostName string, protocol string, headers map[string]string, expectedResponse string) (response string, err error) { url := protocol + "://" + routerUrl var tlsConfig *tls.Config routerAddress := getRouteAddress() dialer := func(network, addr string) (net.Conn, error) { if _, port, err := net.SplitHostPort(addr); err == nil { return net.Dial(network, fmt.Sprintf("%s:%s", routerAddress, port)) } return net.Dial(network, fmt.Sprintf("%s:%s", routerAddress, "80")) } tlsDialer := func(network, addr string, config *tls.Config) (*tls.Conn, error) { if _, port, err := net.SplitHostPort(addr); err == nil { return tls.Dial(network, fmt.Sprintf("%s:%s", routerAddress, port), config) } return tls.Dial(network, fmt.Sprintf("%s:%s", routerAddress, "443"), config) } if protocol == "https" || protocol == "wss" { tlsConfig = &tls.Config{ InsecureSkipVerify: true, ServerName: hostName, } } switch protocol { case "http", "https": httpClient := &http.Client{Transport: knet.SetTransportDefaults(&http.Transport{ Dial: dialer, TLSClientConfig: tlsConfig, }), } req, err := http.NewRequest("GET", url, nil) if err != nil { return "", err } for name, value := range headers { req.Header.Set(name, value) } req.Host = hostName resp, err := httpClient.Do(req) if err != nil { return "", err } defer resp.Body.Close() switch { case resp.StatusCode == 503: return "", ErrUnavailable case resp.StatusCode == 401: return "", ErrUnauthenticated case resp.StatusCode >= 400: return "", fmt.Errorf("GET of %s returned: %d", url, resp.StatusCode) } respBody, err := ioutil.ReadAll(resp.Body) cookies := resp.Cookies() for _, cookie := range cookies { if len(cookie.Name) != 32 || len(cookie.Value) != 32 { return "", fmt.Errorf("GET of %s returned bad cookie %s=%s", url, cookie.Name, cookie.Value) } } return string(respBody), err case "ws", "wss": origin := fmt.Sprintf("http://%s/", tr.GetDefaultLocalAddress()) wsConfig, err := websocket.NewConfig(url, origin) if err != nil { return "", err } port := 80 if protocol == "wss" { port = 443 } if _, _, err := net.SplitHostPort(hostName); err == nil { wsConfig.Location.Host = hostName } else { wsConfig.Location.Host = fmt.Sprintf("%s:%d", hostName, port) } var conn net.Conn if tlsConfig == nil { conn, err = dialer("tcp", wsConfig.Location.Host) } else { conn, err = tlsDialer("tcp", wsConfig.Location.Host, tlsConfig) } if err != nil { return "", err } ws, err := websocket.NewClient(wsConfig, conn) if err != nil { if err == websocket.ErrBadStatus { return "", ErrUnavailable } return "", err } _, err = ws.Write([]byte(expectedResponse)) if err != nil { return "", err } var msg = make([]byte, len(expectedResponse)) _, err = ws.Read(msg) if err != nil { return "", err } return string(msg), nil } return "", errors.New("Unrecognized protocol in getRoute") }