def request(self, operation, url, data=None, headers=None):
    """Performs an HTTP call to the server, supports GET, POST, PUT, and 
    DELETE.

    Usage example, perform and HTTP GET on http://www.google.com/:
      import atom.http
      client = atom.http.HttpClient()
      http_response = client.request('GET', 'http://www.google.com/')

    Args:
      operation: str The HTTP operation to be performed. This is usually one
          of 'GET', 'POST', 'PUT', or 'DELETE'
      data: filestream, list of parts, or other object which can be converted
          to a string. Should be set to None when performing a GET or DELETE.
          If data is a file-like object which can be read, this method will 
          read a chunk of 100K bytes at a time and send them. 
          If the data is a list of parts to be sent, each part will be 
          evaluated and sent.
      url: The full URL to which the request should be sent. Can be a string
          or atom.url.Url.
      headers: dict of strings. HTTP headers which should be sent
          in the request. 
    """
    all_headers = self.headers.copy()
    if headers:
      all_headers.update(headers)

    # If the list of headers does not include a Content-Length, attempt to
    # calculate it based on the data object.
    if data and 'Content-Length' not in all_headers:
      if isinstance(data, str):
        all_headers['Content-Length'] = str(len(data))
      else:
        raise atom.http_interface.ContentLengthRequired('Unable to calculate '
            'the length of the data parameter. Specify a value for '
            'Content-Length')

    # Set the content type to the default value if none was set.
    if 'Content-Type' not in all_headers:
      all_headers['Content-Type'] = DEFAULT_CONTENT_TYPE

    if self.v2_http_client is not None:
      http_request = atom.http_core.HttpRequest(method=operation)
      atom.http_core.Uri.parse_uri(str(url)).modify_request(http_request)
      http_request.headers = all_headers
      if data:
        http_request._body_parts.append(data)
      return self.v2_http_client.request(http_request=http_request)

    if not isinstance(url, atom.url.Url):
      if isinstance(url, str):
        url = atom.url.parse_url(url)
      else:
        raise atom.http_interface.UnparsableUrlObject('Unable to parse url '
            'parameter because it was not a string or atom.url.Url')
    
    connection = self._prepare_connection(url, all_headers)

    if self.debug:
      connection.debuglevel = 1

    connection.putrequest(operation, self._get_access_url(url), 
        skip_host=True)
    if url.port is not None:
      connection.putheader('Host', '%s:%s' % (url.host, url.port))
    else:
      connection.putheader('Host', url.host)

    # Overcome a bug in Python 2.4 and 2.5
    # httplib.HTTPConnection.putrequest adding
    # HTTP request header 'Host: www.google.com:443' instead of
    # 'Host: www.google.com', and thus resulting the error message
    # 'Token invalid - AuthSub token has wrong scope' in the HTTP response.
    if (url.protocol == 'https' and int(url.port or 443) == 443 and
        hasattr(connection, '_buffer') and
        isinstance(connection._buffer, list)):
      header_line = 'Host: %s:443' % url.host
      replacement_header_line = 'Host: %s' % url.host
      try:
        connection._buffer[connection._buffer.index(header_line)] = (
            replacement_header_line)
      except __HOLE__:  # header_line missing from connection._buffer
        pass

    # Send the HTTP headers.
    for header_name in all_headers:
      connection.putheader(header_name, all_headers[header_name])
    connection.endheaders()

    # If there is data, send it in the request.
    if data:
      if isinstance(data, list):
        for data_part in data:
          _send_data_part(data_part, connection)
      else:
        _send_data_part(data, connection)

    # Return the HTTP Response from the server.
    return connection.getresponse()
dataset/ETHPy150Open kuri65536/python-for-android/python3-alpha/python-libs/atom/http.py/HttpClient.request