def do_request(uri, method, body=None, query=None, headers=None):

    LOG.debug("do_request: uri=%s, method=%s" % (uri, method))
    LOG.debug("do_request: body=%s" % body)
    LOG.debug("do_request: headers=%s" % headers)

    if body != None:
        data = json.dumps(body)
    else:
        data = '{}'

    if query:
        uri += '?' + urllib.urlencode(query)

    if headers == None:
        headers = {}

    h = httplib2.Http()
    response, content = h.request(uri, method, data, headers=headers)

    LOG.debug("do_request: response=%s" % response)
    LOG.debug("do_request: content=%s" % content)

    if int(response['status']) > 300:
        e = exc.get_exception(response['status'])(content)
        LOG.error("Raising an exeption: (%r): %r" % (e, str(e)))
        raise e
    try:
        body = json.loads(content) if content else None
        return response, body
    except ValueError:
        return response, content
    def _do_request(self, uri, method, body='{}', headers={}, retries_left=1):
        if not method == 'DELETE':
            if not('Content-Type' in headers and \
                        headers['Content-Type']):
                headers['Content-Type'] = 'application/json'

        if self.auth:
            headers.update(self.auth.generate_auth_header())

        with self.sem:
            response, content = self.h.request(uri, method, body,
                                               headers=headers)

        boarder = '=' * 20
        req = '(%s on %s) ' % (method, uri)
        LOG.debug(boarder)
        LOG.debug('Req: %s',  req)
        LOG.debug('Req headers: %s', headers)
        LOG.debug('Req Body: %s' % body)
        LOG.debug('Resp: %s' % response)
        LOG.debug('Resp Body: %s' % content)
        LOG.debug(boarder)

        if int(response['status']) > 300:
            # In case of authentication error, try re-generating auth header
            if self.auth and response['status'] == '401' and retries_left > 0:
                self.auth.get_token(regenerate=True)
                retries_left -= 1
                return self._do_request(uri, method, body, headers, retries_left)

            LOG.error("%s got an error status %s", req, response['status'])
            e = exc.get_exception(response['status'])(content)
            LOG.error("Raising an exeption: (%r): %r" % (e, str(e)))
            raise e
        try:
            body = json.loads(content) if content else None
            return response, body
        except ValueError:
            return response, content