'Sends an RPC and returns the response.
Args:
request_path: The path to send the request to, eg /api/appversion/create.
payload: The body of the request, or None to send an empty request.
content_type: The Content-Type header to use.
timeout: timeout in seconds; default None i.e. no timeout.
(Note: for large requests on OS X, the timeout doesn\'t work right.)
Any keyword arguments are converted into query string parameters.
Returns:
The response body, as a string.
Raises:
AuthPermanentFail: If authorization failed in a permanent way.
urllib2.HTTPError: On most HTTP errors.'

def Send(self, request_path, payload='', content_type='application/octet-stream', timeout=None, **kwargs):

    self.http = self.http_class(cache=self.memory_cache, ca_certs=self.certpath, disable_ssl_certificate_validation=(not self.cert_file_available))
    self.http.follow_redirects = False
    self.http.timeout = timeout
    url = ('%s://%s%s' % (self.scheme, self.host, request_path))
    if kwargs:
        url += ('?' + urllib.urlencode(sorted(kwargs.items())))
    headers = {}
    if self.extra_headers:
        headers.update(self.extra_headers)
    headers['X-appcfg-api-version'] = '1'
    if (payload is not None):
        method = 'POST'
        headers['content-length'] = str(len(payload))
        headers['Content-Type'] = content_type
    else:
        method = 'GET'
    if self.host_override:
        headers['Host'] = self.host_override
    rpc_errors = 0
    auth_errors = [0]
    conflict_errors = 0
    timeout_errors = 0
    def NeedAuth():
        "Marker    that    we    need    auth;    it'll    actually    be    tried    next    time    around."
        auth_errors[0] += 1
        logger.debug('Attempting    to    auth.    This    is    try    %s    of    %s.', auth_errors[0], self.auth_max_errors)
        if (auth_errors[0] > self.auth_max_errors):
            RaiseHttpError(url, response_info, response, 'Too    many    auth    attempts.')
    while ((rpc_errors < self.rpc_max_errors) and (conflict_errors < self.conflict_max_errors) and (timeout_errors < self.timeout_max_errors)):
        self._Authenticate(self.http, (auth_errors[0] > 0))
        logger.debug('Sending    request    to    %s    headers=%s    body=%s', url, headers, ((self.debug_data and payload) or (payload and 'ELIDED') or ''))
        try:
            (response_info, response) = self.http.request(url, method=method, body=payload, headers=headers)
        except client.AccessTokenRefreshError as e:
            logger.info('Got    access    token    error', exc_info=1)
            response_info = httplib2.Response({'status': 401})
            response_info.reason = str(e)
            response = ''
        status = response_info.status
        if (status == 200):
            return response
        logger.debug('Got    http    error    %s.', response_info.status)
        if (status == 401):
            NeedAuth()
            continue
        elif (status == 408):
            timeout_errors += 1
            logger.debug('Got    timeout    error    %s    of    %s.    Retrying    in    %s    seconds', timeout_errors, self.timeout_max_errors, _TIMEOUT_WAIT_TIME)
            time.sleep(_TIMEOUT_WAIT_TIME)
            continue
        elif (status == 409):
            conflict_errors += 1
            wait_time = random.randint(0, 10)
            logger.debug('Got    conflict    error    %s    of    %s.    Retrying    in    %s    seconds.', conflict_errors, self.conflict_max_errors, wait_time)
            time.sleep(wait_time)
            continue
        elif ((status >= 500) and (status < 600)):
            rpc_errors += 1
            logger.debug('Retrying.    This    is    attempt    %s    of    %s.', rpc_errors, self.rpc_max_errors)
            continue
        elif (status == 302):
            loc = response_info.get('location')
            logger.debug('Got    302    redirect.    Location:    %s', loc)
            if (loc.startswith('https://www.google.com/accounts/ServiceLogin') or re.match('https://www\\.google\\.com/a/[a-z0-9.-]+/ServiceLogin', loc)):
                NeedAuth()
                continue
            elif loc.startswith(('http://%s/_ah/login' % (self.host,))):
                RaiseHttpError(url, response_info, response, 'dev_appserver    login    not    supported')
            else:
                RaiseHttpError(url, response_info, response, ('Unexpected    redirect    to    %s' % loc))
        else:
            logger.debug('Unexpected    results:    %s', response_info)
            RaiseHttpError(url, response_info, response, ('Unexpected    HTTP    status    %s' % status))
    logging.info('Too    many    retries    for    url    %s', url)
    RaiseHttpError(url, response_info, response)
