'Search through all the base URLs to connect to one that works.
This is a thin wrapper around requests.request() so most parameters are
documented there.
Args:
path: The URL path to access in this endpoint.
verify_cb: A callback which should return True if the response is
reasonable. This is used to detect if we are able to talk to the
correct endpoint. If not we try a different endpoint/proxy combination.
data: Parameters to send in POST bodies (See Requests documentation).
params: Parameters to send in GET URLs (See Requests documentation).
headers: Additional headers (See Requests documentation)
method: The HTTP method to use. If not set we select one automatically.
timeout: See Requests documentation.
Returns:
an HTTPObject() instance with the correct error code set.'

def OpenServerEndpoint(self, path, verify_cb=(lambda x: True), data=None, params=None, headers=None, method='GET', timeout=None):

    tries = 0
    last_error = HTTPObject(code=404)
    while (tries < len(self.base_urls)):
        base_url_index = (self.last_base_url_index % len(self.base_urls))
        active_base_url = self.base_urls[base_url_index]
        result = self.OpenURL(self._ConcatenateURL(active_base_url, path), data=data, params=params, headers=headers, method=method, timeout=timeout, verify_cb=verify_cb)
        if (not result.Success()):
            tries += 1
            self.last_base_url_index += 1
            last_error = result
            continue
        self.active_base_url = active_base_url
        return result
    logging.info('Could    not    connect    to    GRR    servers    %s,    directly    or    through    these    proxies:    %s.', self.base_urls, self.proxies)
    return last_error
