'Do the actual request using the connection object
and also follow one level of redirects if necessary'

def _request(self, conn, host, absolute_uri, request_uri, method, body, headers, redirections, cachekey):

    auths = [(auth.depth(request_uri), auth) for auth in self.authorizations if auth.inscope(host, request_uri)]
    auth = ((auths and sorted(auths)[0][1]) or None)
    if auth:
        auth.request(method, request_uri, headers, body)
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
    if auth:
        if auth.response(response, body):
            auth.request(method, request_uri, headers, body)
            (response, content) = self._conn_request(conn, request_uri, method, body, headers)
            response._stale_digest = 1
    if (response.status == 401):
        for authorization in self._auth_from_challenge(host, request_uri, headers, response, content):
            authorization.request(method, request_uri, headers, body)
            (response, content) = self._conn_request(conn, request_uri, method, body, headers)
            if (response.status != 401):
                self.authorizations.append(authorization)
                authorization.response(response, body)
                break
    if (self.follow_all_redirects or (method in ['GET', 'HEAD']) or (response.status == 303)):
        if (self.follow_redirects and (response.status in [300, 301, 302, 303, 307])):
            if redirections:
                if ((not response.has_key('location')) and (response.status != 300)):
                    raise RedirectMissingLocation(_('Redirected    but    the    response    is    missing    a    Location:    header.'), response, content)
                if response.has_key('location'):
                    location = response['location']
                    (scheme, authority, path, query, fragment) = parse_uri(location)
                    if (authority is None):
                        response['location'] = urlparse.urljoin(absolute_uri, location)
                if ((response.status == 301) and (method in ['GET', 'HEAD'])):
                    response['-x-permanent-redirect-url'] = response['location']
                    if (not response.has_key('content-location')):
                        response['content-location'] = absolute_uri
                    _updateCache(headers, response, content, self.cache, cachekey)
                if headers.has_key('if-none-match'):
                    del headers['if-none-match']
                if headers.has_key('if-modified-since'):
                    del headers['if-modified-since']
                if response.has_key('location'):
                    location = response['location']
                    old_response = copy.deepcopy(response)
                    if (not old_response.has_key('content-location')):
                        old_response['content-location'] = absolute_uri
                    redirect_method = ((((response.status == 303) and (method not in ['GET', 'HEAD'])) and 'GET') or method)
                    (response, content) = self.request(location, redirect_method, body=body, headers=headers, redirections=(redirections - 1))
                    response.previous = old_response
            else:
                raise RedirectLimit(_('Redirected    more    times    than    rediection_limit    allows.'), response, content)
        elif ((response.status in [200, 203]) and (method == 'GET')):
            if (not response.has_key('content-location')):
                response['content-location'] = absolute_uri
            _updateCache(headers, response, content, self.cache, cachekey)
    return (response, content)
