def test_http_proxy(http_server, monkeypatch, test_port): test_host = 'www.foobarz.invalid' test_path = '/someurl?barf' get_path = None def do_GET(self): nonlocal get_path get_path = self.path self.send_response(200) self.send_header("Content-Type", 'application/octet-stream') self.send_header("Content-Length", '0') self.end_headers() monkeypatch.setattr(MockRequestHandler, 'do_GET', do_GET) conn = HTTPConnection(test_host, test_port, proxy=(http_server.host, http_server.port)) try: conn.send_request('GET', test_path) resp = conn.read_response() assert resp.status == 200 conn.discard() finally: conn.disconnect() if test_port is None: exp_path = 'http://%s%s' % (test_host, test_path) else: exp_path = 'http://%s:%d%s' % (test_host, test_port, test_path) assert get_path == exp_path
def _get_access_token(self): log.info('Requesting new access token') headers = CaseInsensitiveDict() headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' body = urllib.parse.urlencode({ 'client_id': OAUTH_CLIENT_ID, 'client_secret': OAUTH_CLIENT_SECRET, 'refresh_token': self.password, 'grant_type': 'refresh_token' }) conn = HTTPConnection('accounts.google.com', 443, proxy=self.proxy, ssl_context=self.ssl_context) try: conn.send_request('POST', '/o/oauth2/token', headers=headers, body=body.encode('utf-8')) resp = conn.read_response() json_resp = self._parse_json_response(resp, conn) if resp.status > 299 or resp.status < 200: assert 'error' in json_resp if 'error' in json_resp: raise AuthenticationError(json_resp['error']) else: self.access_token[self.password] = json_resp['access_token'] finally: conn.disconnect()
def test_invalid_ssl(): check_http_connection() # Don't load certificates context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.options |= ssl.OP_NO_SSLv2 context.verify_mode = ssl.CERT_REQUIRED conn = HTTPConnection(SSL_TEST_HOST, ssl_context=context) with pytest.raises(ssl.SSLError): conn.send_request('GET', '/') conn.disconnect()
def _get_access_token(self): log.info('Requesting new access token') headers = CaseInsensitiveDict() headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' body = urlencode({'client_id': OAUTH_CLIENT_ID, 'client_secret': OAUTH_CLIENT_SECRET, 'refresh_token': self.password, 'grant_type': 'refresh_token' }) conn = HTTPConnection('accounts.google.com', 443, proxy=self.proxy, ssl_context=self.ssl_context) try: conn.send_request('POST', '/o/oauth2/token', headers=headers, body=body.encode('utf-8')) resp = conn.read_response() if resp.status > 299 or resp.status < 200: raise HTTPError(resp.status, resp.reason, resp.headers) content_type = resp.headers.get('Content-Type', None) if content_type: hit = re.match(r'application/json(?:; charset="(.+)")?$', resp.headers['Content-Type'], re.IGNORECASE) else: hit = None if not hit: log.error('Unexpected server reply when refreshing access token:\n%s', self._dump_response(resp)) raise RuntimeError('Unable to parse server response') charset = hit.group(1) or 'utf-8' body = conn.readall().decode(charset) resp_json = json.loads(body) if not isinstance(resp_json, dict): log.error('Invalid json server response. Expected dict, got:\n%s', body) raise RuntimeError('Unable to parse server response') if 'error' in resp_json: raise AuthenticationError(resp_json['error']) if 'access_token' not in resp_json: log.error('Unable to find access token in server response:\n%s', body) raise RuntimeError('Unable to parse server response') self.access_token[self.password] = resp_json['access_token'] finally: conn.disconnect()
def test_connect_proxy(http_server, monkeypatch, test_port): test_host = 'www.foobarz.invalid' test_path = '/someurl?barf' connect_path = None def do_CONNECT(self): # Pretend we're the remote server too nonlocal connect_path connect_path = self.path self.send_response(200) self.end_headers() self.close_connection = 0 monkeypatch.setattr(MockRequestHandler, 'do_CONNECT', do_CONNECT, raising=False) get_path = None def do_GET(self): nonlocal get_path get_path = self.path self.send_response(200) self.send_header("Content-Type", 'application/octet-stream') self.send_header("Content-Length", '0') self.end_headers() monkeypatch.setattr(MockRequestHandler, 'do_GET', do_GET) # We don't *actually* want to establish SSL, that'd be # to complex for our mock server monkeypatch.setattr('ssl.match_hostname', lambda x, y: True) conn = HTTPConnection(test_host, test_port, proxy=(http_server.host, http_server.port), ssl_context=FakeSSLContext()) try: conn.send_request('GET', test_path) resp = conn.read_response() assert resp.status == 200 conn.discard() finally: conn.disconnect() if test_port is None: test_port = 443 exp_path = '%s:%d' % (test_host, test_port) assert connect_path == exp_path assert get_path == test_path
def test_connect_ssl(): check_http_connection() ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context.options |= ssl.OP_NO_SSLv2 ssl_context.verify_mode = ssl.CERT_REQUIRED ssl_context.set_default_verify_paths() conn = HTTPConnection(SSL_TEST_HOST, ssl_context=ssl_context) conn.send_request('GET', '/') resp = conn.read_response() assert resp.status in (200, 301, 302) assert resp.path == '/' conn.discard() conn.disconnect()
def __call__(self, url: str, method: str = 'GET', body=None, headers=None, timeout=None): # https://github.com/googleapis/google-auth-library-python/issues/318 if not isinstance(body, bytes): body = str(body).encode('ascii') if timeout is not None: raise ValueError('*timeout* argument is not supported') hit = re.match(r'^(https?)://([^:/]+)(?::(\d+))?(.*)$', url) if not hit: raise ValueError('Unsupported URL: ' + url) if hit.group(1) == 'https': ssl_context = self.ssl_context proxy = self.ssl_proxy else: ssl_context = None proxy = self.proxy hostname = hit.group(2) if hit.group(3): port = int(hit.group(3)) elif ssl_context: port = 443 else: port = 80 path = hit.group(4) try: conn = self.conn_pool[(hostname, port)] except KeyError: conn = HTTPConnection(hostname, port, proxy=proxy, ssl_context=ssl_context) self.conn_pool[(hostname, port)] = conn try: conn.send_request(method, path, headers=headers, body=body) resp = conn.read_response() except (dugong.ConnectionClosed, dugong.InvalidResponse, dugong.UnsupportedResponse, dugong.ConnectionTimedOut, dugong.HostnameNotResolvable, dugong.DNSUnavailable, ssl.SSLError) as exc: raise g_auth.exceptions.TransportError(exc) return Namespace(status=resp.status, headers=resp.headers, data=conn.readall())
def test_connect_proxy(http_server, monkeypatch, test_port): test_host = 'www.foobarz.invalid' test_path = '/someurl?barf' connect_path = None def do_CONNECT(self): # Pretend we're the remote server too nonlocal connect_path connect_path = self.path self.send_response(200) self.end_headers() self.close_connection = 0 monkeypatch.setattr(MockRequestHandler, 'do_CONNECT', do_CONNECT, raising=False) get_path = None def do_GET(self): nonlocal get_path get_path = self.path self.send_response(200) self.send_header("Content-Type", 'application/octet-stream') self.send_header("Content-Length", '0') self.end_headers() monkeypatch.setattr(MockRequestHandler, 'do_GET', do_GET) # We don't *actually* want to establish SSL, that'd be # to complex for our mock server monkeypatch.setattr('ssl.match_hostname', lambda x,y: True) conn = HTTPConnection(test_host, test_port, proxy=(http_server.host, http_server.port), ssl_context=FakeSSLContext()) try: conn.send_request('GET', test_path) resp = conn.read_response() assert resp.status == 200 conn.discard() finally: conn.disconnect() if test_port is None: test_port = 443 exp_path = '%s:%d' % (test_host, test_port) assert connect_path == exp_path assert get_path == test_path