docs: def do_request(self, method, url, data=None, headers=None, params=None):
          """
          Handle API requests / responses transport
  
          :param method: HTTP method to use as string
          :param data: Any data as PyDict (will be converted to XML string)
          :param headers: Any data as PyDict
          :return: If response is XML then an xml.etree.ElementTree else the raw content
          :raise: Any unsuccessful HTTP response code if fail_mode=raise
          """
  
          response_content = None
          if data:
              if headers:
                  headers.update({'Content-Type': 'application/xml'})
              else:
                  headers = {'Content-Type': 'application/xml'}
  
              if self._debug:
                  print md.parseString(data).toprettyxml()
  
          response = self._session.request(method, url, headers=headers, params=params, data=data)
  
          if 'content-type' in response.headers:
              if response.headers['content-type'].find('application/xml') != -1:
                  response_content = xmloperations.xml_to_dict(et.fromstring(response.content))
              elif response.headers['content-type'].find('application/json') != -1:
                  response_content = json.loads(response.content)
              else:
                  response_content = response.content
  
          response_odict = OrderedDict([('status', response.status_code), ('body', response_content),
                                        ('location', None), ('objectId', None), ('Etag', None)])
  
          if 'location' in response.headers:
              response_odict['location'] = response.headers['location']
              response_odict['objectId'] = response.headers['location'].split('/')[-1]
  
          if 'Etag' in response.headers:
              response_odict['Etag'] = response.headers['Etag']
  
          if response.status_code not in [200, 201, 202, 204]:
              if self.fail_mode == 'exit':
                  sys.exit('receive bad status code {}\n{}'.format(response.status_code, response_content))
              elif self.fail_mode == 'raise':
                  raise NsxError(response.status_code, response_content)
              elif self.fail_mode == 'continue':
                  pass
  
          return response_odict