func (c *Client) readLoop(done chan bool) { for { _, data, err := c.Conn.ReadMessage() if err != nil { done <- true logrus.Warnf("c.Conn.ReadMessage: %v", err) return } switch data[0] { case '0': // data buf, err := base64.StdEncoding.DecodeString(string(data[1:])) if err != nil { logrus.Warnf("Invalid base64 content: %q", data[1:]) } fmt.Print(string(buf)) case '1': // pong case '2': // new title newTitle := string(data[1:]) fmt.Printf("\033]0;%s\007", newTitle) case '3': // json prefs logrus.Debugf("Unhandled protocol message: json pref: %s", string(data)) case '4': // autoreconnect logrus.Debugf("Unhandled protocol message: autoreconnect: %s", string(data)) default: logrus.Warnf("Unhandled protocol message: %s", string(data)) } } }
func (c *Client) pingLoop() { for { logrus.Debugf("Sending ping") c.write([]byte("1")) time.Sleep(30 * time.Second) } }
// Connect tries to dial a websocket server func (c *Client) Connect() error { // Retrieve AuthToken authToken, err := c.GetAuthToken() if err != nil { return err } logrus.Debugf("Auth-token: %q", authToken) // Open WebSocket connection target, header, err := GetWebsocketURL(c.URL) if err != nil { return err } logrus.Debugf("Connecting to websocket: %q", target.String()) conn, _, err := c.Dialer.Dial(target.String(), *header) if err != nil { return err } c.Conn = conn // Pass arguments and auth-token query, err := GetURLQuery(c.URL) if err != nil { return err } querySingle := querySingleType{ Arguments: "?" + query.Encode(), AuthToken: authToken, } json, err := json.Marshal(querySingle) if err != nil { logrus.Errorf("Failed to parse init message %v", err) return err } // Send Json logrus.Debugf("Sending arguments and auth-token") err = c.write(json) if err != nil { return err } go c.pingLoop() return nil }
// GetAuthToken retrieves an Auth Token from dynamic auth_token.js file func (c *Client) GetAuthToken() (string, error) { target, header, err := GetAuthTokenURL(c.URL) if err != nil { return "", err } logrus.Debugf("Fetching auth token auth-token: %q", target.String()) req, err := http.NewRequest("GET", target.String(), nil) req.Header = *header client := http.Client{} resp, err := client.Do(req) if err != nil { return "", err } switch resp.StatusCode { case 200: // Everything is OK default: return "", fmt.Errorf("unknown status code: %d (%s)", resp.StatusCode, http.StatusText(resp.StatusCode)) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } re := regexp.MustCompile("var gotty_auth_token = '(.*)'") output := re.FindStringSubmatch(string(body)) if len(output) == 0 { return "", fmt.Errorf("Cannot fetch GoTTY auth-token, please upgrade your GoTTY server.") } return output[1], nil }