Пример #1
0
// Dial will open a websocket to socketURL, pass the display string to the
// server and return a DisplayClient implementing ioext.ReadWriteCloser using
// the websocket.
//
// Use ListDisplays() to find available displays.
func Dial(socketURL string, display string) (*DisplayClient, error) {
	// Parse socketURL and get query string
	u, err := url.Parse(socketURL)
	if err != nil {
		return nil, fmt.Errorf("Invalid socketURL: %s, parsing error: %s",
			socketURL, err)
	}
	q := u.Query()

	// Ensure the URL has ws or wss as scheme
	switch u.Scheme {
	case "http":
		u.Scheme = "ws"
	case "https":
		u.Scheme = "wss"
	}

	// Set display
	q.Set("display", display)

	// Set querystring on url
	u.RawQuery = q.Encode()

	// Dial up to the constructed URL
	ws, res, err := dialer.Dial(u.String(), nil)

	// Upgrade failed then we most likely got some error response
	if err == websocket.ErrBadHandshake {
		// Attempt to read and parse the body (limit to 2MiB for sanity)
		data, _ := ioext.ReadAtMost(res.Body, 2*1024*1024)
		var errorMsg displayconsts.ErrorMessage
		perr := json.Unmarshal(data, &errorMsg)
		if perr == nil {
			return nil, &errorMsg
		}
		// return a generic error message if body parsing failed
		return nil, fmt.Errorf("Failed to connect to display, statusCode: %d",
			res.StatusCode)
	}
	if err != nil {
		return nil, fmt.Errorf("Failed to open websocket, error: %s", err)
	}

	// Return a new DisplayClient wrapping the websocket
	return New(ws), nil
}
Пример #2
0
func (g *guestTools) poll(ctx context.Context) {
	// Poll the metaservice for an action to perform
	req, err := http.NewRequest(http.MethodGet, g.url("engine/v1/poll"), nil)
	if err != nil {
		g.log.Panicln("Failed to create polling request, error: ", err)
	}

	// Do request with a timeout
	c, _ := context.WithTimeout(ctx, pollTimeout)
	res, err := ctxhttp.Do(c, nil, req)
	//res, res := http.DefaultClient.Do(req)
	if err != nil {
		g.log.Info("Poll request failed, error: ", err)

		// if this wasn't a deadline exceeded error, we'll sleep a second to avoid
		// spinning the CPU while waiting for DHCP to come up.
		if err != context.DeadlineExceeded && err != context.Canceled {
			time.Sleep(1 * time.Second)
		}
		return
	}

	// Read the request body
	defer res.Body.Close()
	data, err := ioext.ReadAtMost(res.Body, 2*1024*1024)
	if err != nil {
		g.log.Error("Failed to read poll request body, error: ", err)
		return
	}

	// Parse the request body
	action := metaservice.Action{}
	err = json.Unmarshal(data, &action)
	if err != nil {
		g.log.Error("Failed to parse poll request body, error: ", err)
		return
	}

	g.dispatchAction(action)
}