codekingpro/portable-devtools
114k
1# Copyright 2016 Google LLC2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14 15"""Transport adapter for http.client, for internal use only."""16 17import http.client as http_client18import logging19import socket20import urllib21 22from google.auth import exceptions23from google.auth import transport24 25_LOGGER = logging.getLogger(__name__)26 27 28class Response(transport.Response):29 """http.client transport response adapter.30 31 Args:32 response (http.client.HTTPResponse): The raw http client response.33 """34 35 def __init__(self, response):36 self._status = response.status37 self._headers = {key.lower(): value for key, value in response.getheaders()}38 self._data = response.read()39 40 @property41 def status(self):42 return self._status43 44 @property45 def headers(self):46 return self._headers47 48 @property49 def data(self):50 return self._data51 52 53class Request(transport.Request):54 """http.client transport request adapter."""55 56 def __call__(57 self, url, method="GET", body=None, headers=None, timeout=None, **kwargs58 ):59 """Make an HTTP request using http.client.60 61 Args:62 url (str): The URI to be requested.63 method (str): The HTTP method to use for the request. Defaults64 to 'GET'.65 body (bytes): The payload / body in HTTP request.66 headers (Mapping): Request headers.67 timeout (Optional(int)): The number of seconds to wait for a68 response from the server. If not specified or if None, the69 socket global default timeout will be used.70 kwargs: Additional arguments passed throught to the underlying71 :meth:`~http.client.HTTPConnection.request` method.72 73 Returns:74 Response: The HTTP response.75 76 Raises:77 google.auth.exceptions.TransportError: If any exception occurred.78 """79 # socket._GLOBAL_DEFAULT_TIMEOUT is the default in http.client.80 if timeout is None:81 timeout = socket._GLOBAL_DEFAULT_TIMEOUT82 83 # http.client doesn't allow None as the headers argument.84 if headers is None:85 headers = {}86 87 # http.client needs the host and path parts specified separately.88 parts = urllib.parse.urlsplit(url)89 path = urllib.parse.urlunsplit(90 ("", "", parts.path, parts.query, parts.fragment)91 )92 93 if parts.scheme != "http":94 raise exceptions.TransportError(95 "http.client transport only supports the http scheme, {}"96 "was specified".format(parts.scheme)97 )98 99 connection = http_client.HTTPConnection(parts.netloc, timeout=timeout)100 101 try:102 _LOGGER.debug("Making request: %s %s", method, url)103 104 connection.request(method, path, body=body, headers=headers, **kwargs)105 response = connection.getresponse()106 return Response(response)107 108 except (http_client.HTTPException, socket.error) as caught_exc:109 new_exc = exceptions.TransportError(caught_exc)110 raise new_exc from caught_exc111 112 finally:113 connection.close()114 