def send_request(self, method, action, body=None,<EOL>headers=None, ipaddr=None):
action = '<STR_LIT>'.join([self.scheme, '<STR_LIT>', action])<EOL>if netaddr.valid_ipv6(ipaddr):<EOL><INDENT>action = action % ("<STR_LIT>" % ipaddr)<EOL><DEDENT>else:<EOL><INDENT>action = action % ipaddr<EOL><DEDENT>config = action + "<STR_LIT>" + body if body else action<EOL>if self.request_cookie:<EOL><INDENT>cookie, verify = self._get_cookie(ipaddr, config)<EOL>headers = {"<STR_LIT>": "<STR_LIT:application/json>",<EOL>"<STR_LIT>": "<STR_LIT>", "<STR_LIT>": cookie}<EOL><DEDENT>else:<EOL><INDENT>if ipaddr not in self.credentials:<EOL><INDENT>raise cexc.NexusCredentialNotFound(switch_ip=ipaddr)<EOL><DEDENT>else:<EOL><INDENT>headers = {'<STR_LIT:Content-Type>': '<STR_LIT:application/json>'}<EOL>security_data = self.credentials[ipaddr]<EOL>verify = security_data[const.HTTPS_CERT_TUPLE]<EOL>if not verify:<EOL><INDENT>verify = security_data[const.HTTPS_VERIFY_TUPLE]<EOL><DEDENT>self.session.auth = (security_data[<NUM_LIT:0>], security_data[<NUM_LIT:1>])<EOL><DEDENT><DEDENT>if self.status != requests.codes.OK:<EOL><INDENT>return {}<EOL><DEDENT>for attempt in range(self.max_retries + <NUM_LIT:1>):<EOL><INDENT>try:<EOL><INDENT>LOG.debug("<STR_LIT>" %<EOL>{"<STR_LIT>": ipaddr, "<STR_LIT:id>": attempt})<EOL>response = self.session.request(<EOL>method,<EOL>action,<EOL>data=body,<EOL>headers=headers,<EOL>verify=verify,<EOL>timeout=self.timeout)<EOL>if (self.request_cookie and<EOL>response.status_code in CREDENTIAL_EXPIRED):<EOL><INDENT>cookie, verify = self._get_cookie(<EOL>ipaddr, config, refresh=True)<EOL>headers = {"<STR_LIT>": "<STR_LIT:application/json>",<EOL>"<STR_LIT>": "<STR_LIT>", "<STR_LIT>": cookie}<EOL>continue<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOG.error(<EOL>"<STR_LIT>",<EOL>{'<STR_LIT>': str(e), '<STR_LIT>': config})<EOL>raise cexc.NexusConfigFailed(nexus_host=ipaddr,<EOL>config=config,<EOL>exc=e)<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>status_string = requests.status_codes._codes[response.status_code][<NUM_LIT:0>]<EOL>if response.status_code in self.accepted_codes:<EOL><INDENT>LOG.debug(<EOL>"<STR_LIT>",<EOL>{'<STR_LIT:status>': status_string,<EOL>'<STR_LIT:code>': response.status_code,<EOL>'<STR_LIT:url>': action})<EOL>output = {}<EOL>if ('<STR_LIT:application/json>' in response.headers['<STR_LIT>'] or<EOL>'<STR_LIT>' in response.headers['<STR_LIT>']):<EOL><INDENT>try:<EOL><INDENT>output = response.json()<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOG.exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT>if '<STR_LIT>' in output:<EOL><INDENT>try:<EOL><INDENT>cli_resp = output['<STR_LIT>']['<STR_LIT>']['<STR_LIT>']<EOL><DEDENT>except Exception:<EOL><INDENT>cli_resp = []<EOL><DEDENT>for cli in cli_resp:<EOL><INDENT>try:<EOL><INDENT>status = int((cli['<STR_LIT:code>']))<EOL><DEDENT>except ValueError:<EOL><INDENT>status = '<STR_LIT>' % cli['<STR_LIT:code>']<EOL><DEDENT>if status not in self.accepted_codes:<EOL><INDENT>excpt = "<STR_LIT>"<EOL>"<STR_LIT>" % str(status)<EOL>raise cexc.NexusConfigFailed(<EOL>nexus_host=ipaddr, config=config,<EOL>exc=excpt)<EOL><DEDENT><DEDENT><DEDENT>return output<EOL><DEDENT>else:<EOL><INDENT>LOG.error(<EOL>"<STR_LIT>",<EOL>{'<STR_LIT:status>': status_string,<EOL>'<STR_LIT:code>': response.status_code,<EOL>'<STR_LIT:url>': action})<EOL>LOG.error("<STR_LIT>",<EOL>{'<STR_LIT>': response.text})<EOL>raise cexc.NexusConfigFailed(nexus_host=ipaddr,<EOL>config=config,<EOL>exc=response.text)<EOL><DEDENT>
Perform the HTTP request.

        The response is in either JSON format or plain text. A GET method will
        invoke a JSON response while a PUT/POST/DELETE returns message from the
        the server in plain text format.
        Exception is raised when server replies with an INTERNAL SERVER ERROR
        status code (500) i.e. an error has occurred on the server or SERVICE
        UNAVAILABLE (404) i.e. server is not reachable.

        :param method: type of the HTTP request. POST, GET, PUT or DELETE
        :param action: path to which the client makes request
        :param body: dict of arguments which are sent as part of the request
        :param headers: header for the HTTP request
        :param server_ip: server_ip for the HTTP request.
        :returns: JSON or plain text in HTTP response