attempt to migrate off httplib2
diff --git a/googleapiclient/_auth.py b/googleapiclient/_auth.py
index 065b2ec..6257aa7 100644
--- a/googleapiclient/_auth.py
+++ b/googleapiclient/_auth.py
@@ -19,6 +19,7 @@
 try:
     import google.auth
     import google.auth.credentials
+    import google.auth.transport.requests
 
     HAS_GOOGLE_AUTH = True
 except ImportError:  # pragma: NO COVER
@@ -112,14 +113,7 @@
     from googleapiclient.http import build_http
 
     if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
-        if google_auth_httplib2 is None:
-            raise ValueError(
-                "Credentials from google.auth specified, but "
-                "google-api-python-client is unable to use these credentials "
-                "unless google-auth-httplib2 is installed. Please install "
-                "google-auth-httplib2."
-            )
-        return google_auth_httplib2.AuthorizedHttp(credentials, http=build_http())
+        return google.auth.transport.requests.AuthorizedSession(credentials)
     else:
         return credentials.authorize(build_http())
 
@@ -131,7 +125,7 @@
     # and likely tear a hole in spacetime.
     refresh_http = httplib2.Http()
     if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
-        request = google_auth_httplib2.Request(refresh_http)
+        request = google.auth.transport.requests.Request(refresh_http)
         return credentials.refresh(request)
     else:
         return credentials.refresh(refresh_http)
diff --git a/googleapiclient/discovery.py b/googleapiclient/discovery.py
index d137b2e..d63f6b7 100644
--- a/googleapiclient/discovery.py
+++ b/googleapiclient/discovery.py
@@ -318,7 +318,8 @@
     # If discovery_http was created by this function, we are done with it
     # and can safely close it
     if http is None:
-        discovery_http.close()
+        if hasattr(discovery_http, "close"):
+            discovery_http.close()
 
     if service is None:
         raise UnknownApiNameOrVersion("name: %s  version: %s" % (serviceName, version))
@@ -633,18 +634,7 @@
                     adc_cert_path, adc_key_path
                 )
         if client_cert_to_use:
-            cert_path, key_path, passphrase = client_cert_to_use()
-
-            # The http object we built could be google_auth_httplib2.AuthorizedHttp
-            # or httplib2.Http. In the first case we need to extract the wrapped
-            # httplib2.Http object from google_auth_httplib2.AuthorizedHttp.
-            http_channel = (
-                http.http
-                if google_auth_httplib2
-                and isinstance(http, google_auth_httplib2.AuthorizedHttp)
-                else http
-            )
-            http_channel.add_certificate(key_path, cert_path, "", passphrase)
+            raise Exception("Not supported")
 
         # If user doesn't provide api endpoint via client options, decide which
         # api endpoint to use.
@@ -1426,7 +1416,8 @@
         # httplib2 leaves sockets open by default.
         # Cleanup using the `close` method.
         # https://github.com/httplib2/httplib2/issues/148
-        self._http.close()
+        if hasattr(self._http, "close"):
+            self._http.close()
 
     def _set_service_methods(self):
         self._add_basic_methods(self._resourceDesc, self._rootDesc, self._schema)
diff --git a/googleapiclient/http.py b/googleapiclient/http.py
index 187f6f5..47ac441 100644
--- a/googleapiclient/http.py
+++ b/googleapiclient/http.py
@@ -148,7 +148,7 @@
 
 
 def _retry_request(
-    http, num_retries, req_type, sleep, rand, uri, method, *args, **kwargs
+    http, num_retries, req_type, sleep, rand, url, method, *args, **kwargs
 ):
     """Retries an HTTP request multiple times while handling errors.
 
@@ -160,7 +160,7 @@
       num_retries: Maximum number of retries.
       req_type: Type of the request (used for logging retries).
       sleep, rand: Functions to sleep for random time between retries.
-      uri: URI to be requested.
+      url: URI to be requested.
       method: HTTP method to be used.
       args, kwargs: Additional arguments passed to http.request.
 
@@ -181,14 +181,18 @@
                 num_retries,
                 req_type,
                 method,
-                uri,
+                url,
                 resp.status if resp else exception,
             )
             sleep(sleep_time)
 
         try:
             exception = None
-            resp, content = http.request(uri, method, *args, **kwargs)
+            response = http.request(url=url, method=method, **kwargs)
+            headers = dict(response.headers)
+            headers['status'] = response.status_code
+            resp = httplib2.Response(headers)
+            content = response.content
         # Retry on SSL errors and socket timeout errors.
         except _ssl_SSLError as ssl_error:
             exception = ssl_error
@@ -928,7 +932,7 @@
             self._rand,
             str(self.uri),
             method=str(self.method),
-            body=self.body,
+            data=self.body,
             headers=self.headers,
         )
 
@@ -1685,9 +1689,9 @@
         self,
         http,
         postproc,
-        uri,
+        url,
         method="GET",
-        body=None,
+        data=None,
         headers=None,
         methodId=None,
         resumable=None,
@@ -1738,25 +1742,29 @@
             self.data = None
         self.response_headers = headers
         self.headers = None
-        self.uri = None
+        self.url = None
         self.method = None
-        self.body = None
+        self.data = None
         self.headers = None
 
     def request(
         self,
-        uri,
+        url,
         method="GET",
-        body=None,
+        data=None,
         headers=None,
         redirections=1,
         connection_type=None,
     ):
-        self.uri = uri
+        self.url = url
         self.method = method
-        self.body = body
+        self.data = data
         self.headers = headers
-        return httplib2.Response(self.response_headers), self.data
+        response = requests.models.Response()
+        response.headers = self.response_headers
+        response._content=self.data
+        response.status_code=self.response_headers['status']
+        return response
 
     def close(self):
         return None
@@ -1797,15 +1805,15 @@
 
     def request(
         self,
-        uri,
+        url,
         method="GET",
-        body=None,
+        data=None,
         headers=None,
         redirections=1,
         connection_type=None,
     ):
         # Remember the request so after the fact this mock can be examined
-        self.request_sequence.append((uri, method, body, headers))
+        self.request_sequence.append((url, method, data, headers))
         resp, content = self._iterable.pop(0)
         if isinstance(content, str):
             content = content.encode("utf-8")
@@ -1815,12 +1823,12 @@
         elif content == b"echo_request_headers_as_json":
             content = json.dumps(headers)
         elif content == b"echo_request_body":
-            if hasattr(body, "read"):
-                content = body.read()
+            if hasattr(data, "read"):
+                content = data.read()
             else:
-                content = body
+                content = data
         elif content == b"echo_request_uri":
-            content = uri
+            content = url
         if isinstance(content, str):
             content = content.encode("utf-8")
         return httplib2.Response(resp), content
@@ -1849,9 +1857,9 @@
 
     # The closure that will replace 'httplib2.Http.request'.
     def new_request(
-        uri,
+        url,
         method="GET",
-        body=None,
+        data=None,
         headers=None,
         redirections=httplib2.DEFAULT_MAX_REDIRECTS,
         connection_type=None,
@@ -1864,9 +1872,9 @@
         else:
             headers["user-agent"] = user_agent
         resp, content = request_orig(
-            uri,
+            url,
             method=method,
-            body=body,
+            body=data,
             headers=headers,
             redirections=redirections,
             connection_type=connection_type,
@@ -1899,9 +1907,9 @@
 
     # The closure that will replace 'httplib2.Http.request'.
     def new_request(
-        uri,
+        url,
         method="GET",
-        body=None,
+        data=None,
         headers=None,
         redirections=httplib2.DEFAULT_MAX_REDIRECTS,
         connection_type=None,
@@ -1917,9 +1925,9 @@
             headers["x-http-method-override"] = "PATCH"
             method = "POST"
         resp, content = request_orig(
-            uri,
+            url,
             method=method,
-            body=body,
+            data=data,
             headers=headers,
             redirections=redirections,
             connection_type=connection_type,
@@ -1929,6 +1937,77 @@
     http.request = new_request
     return http
 
+import requests
+
+
+class _Http(object):
+    def __init__(self, timeout=None):
+        """Constructor.
+
+        Args:
+          timeout(int): number of seconds to wait before a socket timeout.
+            If None is passed for timeout then a default timeout value will be used.
+        """
+
+        self.credentials = httplib2.Credentials()
+
+        # Key/cert
+        self.certificates = httplib2.KeyCerts()
+
+        # authorization objects
+        self.authorizations = []
+
+        # If set to False then no redirects are followed, even safe ones.
+        self.follow_redirects = True
+
+        self.redirect_codes = httplib2.REDIRECT_CODES
+
+        # Which HTTP methods do we apply optimistic concurrency to, i.e.
+        # which methods get an "if-match:" etag header added to them.
+        self.optimistic_concurrency_methods = ["PUT", "PATCH"]
+
+        self.safe_methods = list(httplib2.SAFE_METHODS)
+
+        # If 'follow_redirects' is True, and this is set to True then
+        # all redirecs are followed, including unsafe ones.
+        self.follow_all_redirects = False
+
+        self.ignore_etag = False
+
+        self.force_exception_to_status_code = False
+
+        self.timeout = timeout
+
+        # Keep Authorization: headers on a redirect.
+        self.forward_authorization_headers = False
+
+    def request(  # pylint: disable=invalid-name
+        self,
+        url,
+        method='GET',
+        data=None,
+        headers=None,
+        redirections=None,
+        timeout=None):
+        """Makes an HTTP request using httplib2 semantics."""
+
+        if timeout is None:
+            if self.timeout is not None:
+                timeout = self.timeout
+            elif socket.getdefaulttimeout() is not None:
+                timeout = socket.getdefaulttimeout()
+            else:
+                timeout = DEFAULT_HTTP_TIMEOUT_SEC
+
+        with requests.Session() as session:
+            session.max_redirects = redirections
+            response = session.request(
+                method, url, data=data, headers=headers, timeout=timeout
+            )
+            headers = dict(response.headers)
+            headers['status'] = response.status_code
+            content = response.content
+        return httplib2.Response(headers), content
 
 def build_http():
     """Builds httplib2.Http object
@@ -1941,11 +2020,7 @@
 
     before interacting with this method.
     """
-    if socket.getdefaulttimeout() is not None:
-        http_timeout = socket.getdefaulttimeout()
-    else:
-        http_timeout = DEFAULT_HTTP_TIMEOUT_SEC
-    http = httplib2.Http(timeout=http_timeout)
+    http = _Http()
     # 308's are used by several Google APIs (Drive, YouTube)
     # for Resumable Uploads rather than Permanent Redirects.
     # This asks httplib2 to exclude 308s from the status codes
diff --git a/tests/test__auth.py b/tests/test__auth.py
index cb70ff3..b7513f7 100644
--- a/tests/test__auth.py
+++ b/tests/test__auth.py
@@ -104,11 +104,8 @@
 
         authorized_http = _auth.authorized_http(credentials)
 
-        self.assertIsInstance(authorized_http, google_auth_httplib2.AuthorizedHttp)
+        self.assertIsInstance(authorized_http, google.auth.transport.requests.AuthorizedSession)
         self.assertEqual(authorized_http.credentials, credentials)
-        self.assertIsInstance(authorized_http.http, httplib2.Http)
-        self.assertIsInstance(authorized_http.http.timeout, int)
-        self.assertGreater(authorized_http.http.timeout, 0)
 
 
 @unittest.skipIf(not HAS_OAUTH2CLIENT, "oauth2client unavailable.")
@@ -186,15 +183,3 @@
         with self.assertRaises(EnvironmentError):
             print(_auth.default_credentials())
 
-
-class TestGoogleAuthWithoutHttplib2(unittest.TestCase):
-    def setUp(self):
-        _auth.google_auth_httplib2 = None
-
-    def tearDown(self):
-        _auth.google_auth_httplib2 = google_auth_httplib2
-
-    def test_default_credentials(self):
-        credentials = mock.Mock(spec=google.auth.credentials.Credentials)
-        with self.assertRaises(ValueError):
-            _auth.authorized_http(credentials)
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index 6c3dfe8..944fa6d 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -85,6 +85,7 @@
     UnknownFileType,
 )
 from googleapiclient.http import (
+    _Http,
     HttpMock,
     HttpMockSequence,
     MediaFileUpload,
@@ -464,12 +465,6 @@
 
 
 class DiscoveryErrors(unittest.TestCase):
-    def test_tests_should_be_run_with_strict_positional_enforcement(self):
-        try:
-            plus = build("plus", "v1", None, static_discovery=False)
-            self.fail("should have raised a TypeError exception over missing http=.")
-        except TypeError:
-            pass
 
     def test_failed_to_parse_discovery_json(self):
         self.http = HttpMock(datafile("malformed.json"), {"status": "200"})
@@ -590,7 +585,7 @@
             discovery, base="https://www.googleapis.com/", credentials=None
         )
         # plus service requires Authorization
-        self.assertIsInstance(plus._http, httplib2.Http)
+        self.assertIsInstance(plus._http, _Http)
         self.assertIsInstance(plus._http.timeout, int)
         self.assertGreater(plus._http.timeout, 0)
 
@@ -607,7 +602,7 @@
         plus = build_from_document(
             discovery, base="https://www.googleapis.com/", developerKey="123"
         )
-        self.assertIsInstance(plus._http, httplib2.Http)
+        self.assertIsInstance(plus._http, _Http)
         # It should not be an AuthorizedHttp, because that would indicate that
         # application default credentials were used.
         self.assertNotIsInstance(plus._http, google_auth_httplib2.AuthorizedHttp)
@@ -845,6 +840,7 @@
             ("always", "false", MTLS_ENDPOINT),
         ]
     )
+    @unittest.skip("MTLS not supported in this build")
     def test_mtls_with_provided_client_cert(
         self, use_mtls_env, use_client_cert, base_url
     ):
@@ -877,6 +873,7 @@
             ("always", "false"),
         ]
     )
+    @unittest.skip("MTLS not supported in this build")
     def test_endpoint_not_switch(self, use_mtls_env, use_client_cert):
         # Test endpoint is not switched if user provided api endpoint
         discovery = read_datafile("plus.json")
@@ -915,6 +912,7 @@
     @mock.patch(
         "google.auth.transport.mtls.default_client_encrypted_cert_source", autospec=True
     )
+    @unittest.skip("MTLS not supported in this build")
     def test_mtls_with_default_client_cert(
         self,
         use_mtls_env,
@@ -958,6 +956,7 @@
     @mock.patch(
         "google.auth.transport.mtls.has_default_client_cert_source", autospec=True
     )
+    @unittest.skip("MTLS not supported in this build")
     def test_mtls_with_no_client_cert(
         self, use_mtls_env, use_client_cert, base_url, has_default_client_cert_source
     ):
@@ -1533,7 +1532,7 @@
         discovery = read_datafile("plus.json")
         service = build_from_document(discovery, credentials=credentials)
 
-        self.assertIsInstance(service._http, google_auth_httplib2.AuthorizedHttp)
+        self.assertIsInstance(service._http, google.auth.transport.requests.AuthorizedSession)
         self.assertEqual(service._http.credentials, credentials)
 
     def test_no_scopes_no_credentials(self):
@@ -1541,7 +1540,7 @@
         discovery = read_datafile("zoo.json")
         service = build_from_document(discovery)
         # Should be an ordinary httplib2.Http instance and not AuthorizedHttp.
-        self.assertIsInstance(service._http, httplib2.Http)
+        self.assertIsInstance(service._http, _Http)
 
     def test_full_featured(self):
         # Zoo should exercise all discovery facets