We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Support for custom authentication objects for requests module
Hi,

Several transport classes are available, one of them is "requests".
Requests supports basic-authentication but far more than that ([0](http://docs.python-requests.org/en/latest/user/advanced/#custom-authentication)). In order to support this a few lines would need to be changed to allow for providing an authentication object ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)).

I have the code ready ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)) for this and am actively using it.

Would you be willing to accept this contribution ?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `elasticsearch/connection/http_requests.py`
Content:
```
1 import time
2 import warnings
3 try:
4     import requests
5     REQUESTS_AVAILABLE = True
6 except ImportError:
7     REQUESTS_AVAILABLE = False
8 
9 from .base import Connection
10 from ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError
11 from ..compat import urlencode
12 
13 class RequestsHttpConnection(Connection):
14     """
15     Connection using the `requests` library.
16 
17     :arg http_auth: optional http auth information as either ':' separated
18         string or a tuple
19     :arg use_ssl: use ssl for the connection if `True`
20     :arg verify_certs: whether to verify SSL certificates
21     :arg ca_certs: optional path to CA bundle. By default standard requests'
22         bundle will be used.
23     :arg client_cert: path to the file containing the private key and the
24         certificate
25     """
26     def __init__(self, host='localhost', port=9200, http_auth=None,
27         use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None,
28         **kwargs):
29         if not REQUESTS_AVAILABLE:
30             raise ImproperlyConfigured("Please install requests to use RequestsHttpConnection.")
31 
32         super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)
33         self.session = requests.session()
34         if http_auth is not None:
35             if not isinstance(http_auth, (tuple, list)):
36                 http_auth = http_auth.split(':', 1)
37             http_auth = tuple(http_auth)
38             self.session.auth = http_auth
39         self.base_url = 'http%s://%s:%d%s' % (
40             's' if use_ssl else '',
41             host, port, self.url_prefix
42         )
43         self.session.verify = verify_certs
44         self.session.cert = client_cert
45         if ca_certs:
46             if not verify_certs:
47                 raise ImproperlyConfigured("You cannot pass CA certificates when verify SSL is off.")
48             self.session.verify = ca_certs
49 
50         if use_ssl and not verify_certs:
51             warnings.warn(
52                 'Connecting to %s using SSL with verify_certs=False is insecure.' % self.base_url)
53 
54     def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):
55         url = self.base_url + url
56         if params:
57             url = '%s?%s' % (url, urlencode(params or {}))
58 
59         start = time.time()
60         try:
61             response = self.session.request(method, url, data=body, timeout=timeout or self.timeout)
62             duration = time.time() - start
63             raw_data = response.text
64         except requests.exceptions.SSLError as e:
65             self.log_request_fail(method, url, body, time.time() - start, exception=e)
66             raise SSLError('N/A', str(e), e)
67         except requests.Timeout as e:
68             self.log_request_fail(method, url, body, time.time() - start, exception=e)
69             raise ConnectionTimeout('TIMEOUT', str(e), e)
70         except requests.ConnectionError as e:
71             self.log_request_fail(method, url, body, time.time() - start, exception=e)
72             raise ConnectionError('N/A', str(e), e)
73 
74         # raise errors based on http status codes, let the client handle those if needed
75         if not (200 <= response.status_code < 300) and response.status_code not in ignore:
76             self.log_request_fail(method, url, body, duration, response.status_code)
77             self._raise_error(response.status_code, raw_data)
78 
79         self.log_request_success(method, url, response.request.path_url, body, response.status_code, raw_data, duration)
80 
81         return response.status_code, response.headers, raw_data
82
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/elasticsearch/connection/http_requests.py b/elasticsearch/connection/http_requests.py
--- a/elasticsearch/connection/http_requests.py
+++ b/elasticsearch/connection/http_requests.py
@@ -1,3 +1,4 @@
+import six
 import time
 import warnings
 try:
@@ -32,8 +33,10 @@
         super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)
         self.session = requests.session()
         if http_auth is not None:
-            if not isinstance(http_auth, (tuple, list)):
-                http_auth = http_auth.split(':', 1)
+            if isinstance(http_auth, (tuple, list)):
+                http_auth = tuple(http_auth)
+            elif isinstance(http_auth, six.string_types):
+                http_auth = tuple(http_auth.split(':', 1))
             http_auth = tuple(http_auth)
             self.session.auth = http_auth
         self.base_url = 'http%s://%s:%d%s' % (

{"golden_diff": "diff --git a/elasticsearch/connection/http_requests.py b/elasticsearch/connection/http_requests.py\n--- a/elasticsearch/connection/http_requests.py\n+++ b/elasticsearch/connection/http_requests.py\n@@ -1,3 +1,4 @@\n+import six\n import time\n import warnings\n try:\n@@ -32,8 +33,10 @@\n         super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)\n         self.session = requests.session()\n         if http_auth is not None:\n-            if not isinstance(http_auth, (tuple, list)):\n-                http_auth = http_auth.split(':', 1)\n+            if isinstance(http_auth, (tuple, list)):\n+                http_auth = tuple(http_auth)\n+            elif isinstance(http_auth, six.string_types):\n+                http_auth = tuple(http_auth.split(':', 1))\n             http_auth = tuple(http_auth)\n             self.session.auth = http_auth\n         self.base_url = 'http%s://%s:%d%s' % (\n", "issue": "Support for custom authentication objects for requests module\nHi,\n\nSeveral transport classes are available, one of them is \"requests\".\nRequests supports basic-authentication but far more than that ([0](http://docs.python-requests.org/en/latest/user/advanced/#custom-authentication)). In order to support this a few lines would need to be changed to allow for providing an authentication object ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)).\n\nI have the code ready ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)) for this and am actively using it.\n\nWould you be willing to accept this contribution ?\n\n", "before_files": [{"content": "import time\nimport warnings\ntry:\n    import requests\n    REQUESTS_AVAILABLE = True\nexcept ImportError:\n    REQUESTS_AVAILABLE = False\n\nfrom .base import Connection\nfrom ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError\nfrom ..compat import urlencode\n\nclass RequestsHttpConnection(Connection):\n    \"\"\"\n    Connection using the `requests` library.\n\n    :arg http_auth: optional http auth information as either ':' separated\n        string or a tuple\n    :arg use_ssl: use ssl for the connection if `True`\n    :arg verify_certs: whether to verify SSL certificates\n    :arg ca_certs: optional path to CA bundle. By default standard requests'\n        bundle will be used.\n    :arg client_cert: path to the file containing the private key and the\n        certificate\n    \"\"\"\n    def __init__(self, host='localhost', port=9200, http_auth=None,\n        use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None,\n        **kwargs):\n        if not REQUESTS_AVAILABLE:\n            raise ImproperlyConfigured(\"Please install requests to use RequestsHttpConnection.\")\n\n        super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)\n        self.session = requests.session()\n        if http_auth is not None:\n            if not isinstance(http_auth, (tuple, list)):\n                http_auth = http_auth.split(':', 1)\n            http_auth = tuple(http_auth)\n            self.session.auth = http_auth\n        self.base_url = 'http%s://%s:%d%s' % (\n            's' if use_ssl else '',\n            host, port, self.url_prefix\n        )\n        self.session.verify = verify_certs\n        self.session.cert = client_cert\n        if ca_certs:\n            if not verify_certs:\n                raise ImproperlyConfigured(\"You cannot pass CA certificates when verify SSL is off.\")\n            self.session.verify = ca_certs\n\n        if use_ssl and not verify_certs:\n            warnings.warn(\n                'Connecting to %s using SSL with verify_certs=False is insecure.' % self.base_url)\n\n    def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):\n        url = self.base_url + url\n        if params:\n            url = '%s?%s' % (url, urlencode(params or {}))\n\n        start = time.time()\n        try:\n            response = self.session.request(method, url, data=body, timeout=timeout or self.timeout)\n            duration = time.time() - start\n            raw_data = response.text\n        except requests.exceptions.SSLError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise SSLError('N/A', str(e), e)\n        except requests.Timeout as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionTimeout('TIMEOUT', str(e), e)\n        except requests.ConnectionError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionError('N/A', str(e), e)\n\n        # raise errors based on http status codes, let the client handle those if needed\n        if not (200 <= response.status_code < 300) and response.status_code not in ignore:\n            self.log_request_fail(method, url, body, duration, response.status_code)\n            self._raise_error(response.status_code, raw_data)\n\n        self.log_request_success(method, url, response.request.path_url, body, response.status_code, raw_data, duration)\n\n        return response.status_code, response.headers, raw_data\n", "path": "elasticsearch/connection/http_requests.py"}], "after_files": [{"content": "import six\nimport time\nimport warnings\ntry:\n    import requests\n    REQUESTS_AVAILABLE = True\nexcept ImportError:\n    REQUESTS_AVAILABLE = False\n\nfrom .base import Connection\nfrom ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError\nfrom ..compat import urlencode\n\nclass RequestsHttpConnection(Connection):\n    \"\"\"\n    Connection using the `requests` library.\n\n    :arg http_auth: optional http auth information as either ':' separated\n        string or a tuple\n    :arg use_ssl: use ssl for the connection if `True`\n    :arg verify_certs: whether to verify SSL certificates\n    :arg ca_certs: optional path to CA bundle. By default standard requests'\n        bundle will be used.\n    :arg client_cert: path to the file containing the private key and the\n        certificate\n    \"\"\"\n    def __init__(self, host='localhost', port=9200, http_auth=None,\n        use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None,\n        **kwargs):\n        if not REQUESTS_AVAILABLE:\n            raise ImproperlyConfigured(\"Please install requests to use RequestsHttpConnection.\")\n\n        super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)\n        self.session = requests.session()\n        if http_auth is not None:\n            if isinstance(http_auth, (tuple, list)):\n                http_auth = tuple(http_auth)\n            elif isinstance(http_auth, six.string_types):\n                http_auth = tuple(http_auth.split(':', 1))\n            http_auth = tuple(http_auth)\n            self.session.auth = http_auth\n        self.base_url = 'http%s://%s:%d%s' % (\n            's' if use_ssl else '',\n            host, port, self.url_prefix\n        )\n        self.session.verify = verify_certs\n        self.session.cert = client_cert\n        if ca_certs:\n            if not verify_certs:\n                raise ImproperlyConfigured(\"You cannot pass CA certificates when verify SSL is off.\")\n            self.session.verify = ca_certs\n\n        if use_ssl and not verify_certs:\n            warnings.warn(\n                'Connecting to %s using SSL with verify_certs=False is insecure.' % self.base_url)\n\n    def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):\n        url = self.base_url + url\n        if params:\n            url = '%s?%s' % (url, urlencode(params or {}))\n\n        start = time.time()\n        try:\n            response = self.session.request(method, url, data=body, timeout=timeout or self.timeout)\n            duration = time.time() - start\n            raw_data = response.text\n        except requests.exceptions.SSLError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise SSLError('N/A', str(e), e)\n        except requests.Timeout as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionTimeout('TIMEOUT', str(e), e)\n        except requests.ConnectionError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionError('N/A', str(e), e)\n\n        # raise errors based on http status codes, let the client handle those if needed\n        if not (200 <= response.status_code < 300) and response.status_code not in ignore:\n            self.log_request_fail(method, url, body, duration, response.status_code)\n            self._raise_error(response.status_code, raw_data)\n\n        self.log_request_success(method, url, response.request.path_url, body, response.status_code, raw_data, duration)\n\n        return response.status_code, response.headers, raw_data\n", "path": "elasticsearch/connection/http_requests.py"}]}