code: func (c *Client) httpRequest(method string, path string, data []byte, headers map[string]string, useCoordinator bool) (*http.Response, []byte, error) {
  	if data == nil {
  		data = []byte{}
  	}
  
  	// try at most maxHosts non-failed hosts; protect against broken cluster.removeHost
  	var response *http.Response
  	var err error
  	for i := 0; i < maxHosts; i++ {
  		host, err := c.host(useCoordinator)
  		if err != nil {
  			return nil, nil, err
  		}
  		response, err = c.doRequest(host, method, path, c.augmentHeaders(headers), bytes.NewReader(data))
  		if err == nil {
  			break
  		}
  		if c.manualServerURI == nil {
  			if useCoordinator {
  				c.coordinatorLock.Lock()
  				c.coordinatorURI = nil
  				c.coordinatorLock.Unlock()
  			} else {
  				c.cluster.RemoveHost(host)
  			}
  		}
  		// TODO: exponential backoff
  		time.Sleep(1 * time.Second)
  	}
  	if response == nil {
  		return nil, nil, ErrTriedMaxHosts
  	}
  	defer response.Body.Close()
  	warning := response.Header.Get("warning")
  	if warning != "" {
  		c.logger.Println(warning)
  	}
  	// TODO: Optimize buffer creation
  	buf, err := ioutil.ReadAll(response.Body)
  	if err != nil {
  		return nil, nil, err
  	}
  	if response.StatusCode < 200 || response.StatusCode >= 300 {
  		err := NewError(fmt.Sprintf("Server error (%d) %s: %s", response.StatusCode, response.Status, string(buf)))
  		return response, buf, err
  	}
  	return response, buf, nil
  }
docs: // httpRequest makes a request to the cluster - use this when you want the
  // client to choose a host, and it doesn't matter if the request goes to a
  // specific host