'Make a request, returning an HTTP response object.
:param method: HTTP verb (GET, POST, PUT, etc.)
:param action: Requested path to append to self.doc_root
:param body: Data to send in the body of the request
:param headers: Headers to send with the request
:param params: Key/value pairs to use in query string
:returns: HTTP response object'

@handle_unauthenticated
def do_request(self, method, action, body=None, headers=None, params=None):

    if (not self.auth_token):
        self._authenticate()
    url = self._construct_url(action, params)
    return self._do_request(method=method, url=url, body=copy.deepcopy(body), headers=copy.deepcopy(headers))
