def test_pac_download_after_session_init(self): sess = PACSession() proxy = 'PROXY %s; DIRECT' % arbitrary_pac_url pac_js = proxy_pac_js_tpl % 'PROXY %s; DIRECT' % arbitrary_pac_url pac = sess.get_pac(js=pac_js) assert proxy == pac.find_proxy_for_url(host='example.org', url='http://example.org')
def test_extend_session_with_pacsession(self): sess = requests.Session() sess = PACSession(session=sess) proxy = 'PROXY %s; DIRECT' % arbitrary_pac_url pac_js = proxy_pac_js_tpl % 'PROXY %s; DIRECT' % arbitrary_pac_url pac = sess.get_pac(js=pac_js) assert proxy == pac.find_proxy_for_url(host='example.org', url='http://example.org')
def test_default_behaviour_no_pac_found(self): sess = PACSession() mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(None), \ _patch_request_base(mock_ok) as request: resp = sess.get(arbitrary_url) assert resp.status_code == 204 request.assert_called_with('GET', arbitrary_url, proxies=None, allow_redirects=ANY)
def test_pac_override_using_request_proxies_parameter(self): sess = PACSession() mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(PACFile(proxy_pac_js)), \ _patch_request_base(mock_ok) as request: for proxies_arg in ({}, proxy_parameter_for_requests('http://manual:80')): sess.get(arbitrary_url, proxies=proxies_arg) request.assert_called_with('GET', arbitrary_url, proxies=proxies_arg, allow_redirects=ANY)
def test_default_behaviour_no_pac_found(self): sess = PACSession() mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(None), \ _patch_request_base(mock_ok) as request: resp = sess.get(arbitrary_url) assert resp.status_code == 204 request.assert_called_with('GET', arbitrary_url, proxies=None, allow_redirects=ANY)
def test_pac_override_using_request_proxies_parameter(self): sess = PACSession() mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(PACFile(proxy_pac_js)), \ _patch_request_base(mock_ok) as request: for proxies_arg in ({}, proxy_parameter_for_requests('http://manual:80')): sess.get(arbitrary_url, proxies=proxies_arg) request.assert_called_with('GET', arbitrary_url, proxies=proxies_arg, allow_redirects=ANY)
def test_default_behaviour_pac_found(self): sess = PACSession() mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(PACFile(proxy_pac_js)), \ _patch_request_base(mock_ok) as request: assert sess.get(arbitrary_url).status_code == 204 request.assert_called_with('GET', arbitrary_url, proxies=fake_proxies_requests_arg, allow_redirects=ANY)
def test_default_behaviour_pac_found(self): sess = PACSession() mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(PACFile(proxy_pac_js)), \ _patch_request_base(mock_ok) as request: assert sess.get(arbitrary_url).status_code == 204 request.assert_called_with('GET', arbitrary_url, proxies=fake_proxies_requests_arg, allow_redirects=ANY)
def test_pac_no_failover_available_exc_case(self): """Special case where proxy fails but there's no DIRECT fallback. Error should bubble up, and all applicable proxies should be tried again in the next request. Proxy failure from exception.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80')) for _ in range(2): with _patch_request_base(side_effect=ProxyError()) as request, \ pytest.raises(ProxyError): sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_pac_no_failover_available_exc_case(self): """Special case where proxy fails but there's no DIRECT fallback. Error should bubble up, and all applicable proxies should be tried again in the next request. Proxy failure from exception.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80')) for _ in range(2): with _patch_request_base(side_effect=ProxyError()) as request, \ pytest.raises(ProxyError): sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_pac_disabled(self): sess = PACSession(pac_enabled=False) mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(PACFile(proxy_pac_js)) as gp, \ _patch_request_base(mock_ok) as request: assert sess.get(arbitrary_url).status_code == 204 gp.assert_not_called() request.assert_called_with('GET', arbitrary_url, proxies=None, allow_redirects=ANY) # When re-enabled, PAC discovery should proceed and be honoured. sess.pac_enabled = True assert sess.get(arbitrary_url).status_code == 204 gp.assert_called_with(recursion_limit=ARBITRARY_HIGH_RECURSION_LIMIT) request.assert_called_with('GET', arbitrary_url, proxies=fake_proxies_requests_arg, allow_redirects=ANY)
def test_pac_failover_to_direct_also_fails(self): """Proxy fails. Next in line is DIRECT keyword, but direct connection also fails. Error should bubble up. Subsequent requests go straight to DIRECT, despite DIRECT failing.""" sess = PACSession(pac=PACFile(proxy_pac_js)) with _patch_request_base(side_effect=ProxyError()) as request: for _ in range(2): with pytest.raises(ProxyError): sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, fake_proxy_url), get_call(arbitrary_url, 'DIRECT'), get_call(arbitrary_url, 'DIRECT'), ])
def test_pac_disabled(self): sess = PACSession(pac_enabled=False) mock_ok = Mock(spec=requests.Response, status_code=204) with _patch_get_pac(PACFile(proxy_pac_js)) as gp, \ _patch_request_base(mock_ok) as request: assert sess.get(arbitrary_url).status_code == 204 gp.assert_not_called() request.assert_called_with('GET', arbitrary_url, proxies=None, allow_redirects=ANY) # When re-enabled, PAC discovery should proceed and be honoured. sess.pac_enabled = True assert sess.get(arbitrary_url).status_code == 204 gp.assert_called_with() request.assert_called_with('GET', arbitrary_url, proxies=fake_proxies_requests_arg, allow_redirects=ANY)
def test_pac_failover_to_direct_also_fails(self): """Proxy fails. Next in line is DIRECT keyword, but direct connection also fails. Error should bubble up. Subsequent requests go straight to DIRECT, despite DIRECT failing.""" sess = PACSession(pac=PACFile(proxy_pac_js)) with _patch_request_base(side_effect=ProxyError()) as request: for _ in range(2): with pytest.raises(ProxyError): sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, fake_proxy_url), get_call(arbitrary_url, 'DIRECT'), get_call(arbitrary_url, 'DIRECT'), ])
def test_pac_failover(self): """First proxy raises error. Transparently fail over to second proxy.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80; DIRECT')) def fake_request(method, url, proxies=None, **kwargs): if proxies and proxies['http'] == 'http://a:80': raise ProxyError() with _patch_request_base(side_effect=fake_request) as request: sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_pac_failover_to_direct(self): """Proxy fails. Next in line is DIRECT keyword.""" sess = PACSession(pac=PACFile(proxy_pac_js)) def fake_request_reject_proxy(method, url, proxies=None, **kwargs): if proxies and proxies['http'] is not None: raise ProxyError() with _patch_request_base(side_effect=fake_request_reject_proxy) as request: sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, fake_proxy_url), get_call(arbitrary_url, 'DIRECT'), ])
def test_pac_failover(self): """First proxy raises error. Transparently fail over to second proxy.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80; DIRECT')) def fake_request(method, url, proxies=None, **kwargs): if proxies and proxies['http'] == 'http://a:80': raise ProxyError() with _patch_request_base(side_effect=fake_request) as request: sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_pac_failover_to_direct(self): """Proxy fails. Next in line is DIRECT keyword.""" sess = PACSession(pac=PACFile(proxy_pac_js)) def fake_request_reject_proxy(method, url, proxies=None, **kwargs): if proxies and proxies['http'] is not None: raise ProxyError() with _patch_request_base(side_effect=fake_request_reject_proxy) as request: sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, fake_proxy_url), get_call(arbitrary_url, 'DIRECT'), ])
def test_failover_using_custom_response_filter(self): """Use a custom response filter to say that HTTP 407 responses are considered a proxy failure, in order to trigger proxy failover.""" def custom_response_filter(response): return response.status_code == 407 proxy_fail_resp = Mock(spec=requests.Response, status_code=407) sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80'), response_proxy_fail_filter=custom_response_filter) with _patch_request_base(proxy_fail_resp) as request: # Both proxies failed due to 407 response, so return value is the same 407. assert sess.get(arbitrary_url).status_code == 407 request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_failover_using_custom_response_filter(self): """Use a custom response filter to say that HTTP 407 responses are considered a proxy failure, in order to trigger proxy failover.""" def custom_response_filter(response): return response.status_code == 407 proxy_fail_resp = Mock(spec=requests.Response, status_code=407) sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80'), response_proxy_fail_filter=custom_response_filter) with _patch_request_base(proxy_fail_resp) as request: # Both proxies failed due to 407 response, so return value is the same 407. assert sess.get(arbitrary_url).status_code == 407 request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_failover_using_custom_exception_criteria(self): """Use a custom request exception filter to say that some arbitrary exception is considered a proxy failure, in order to trigger proxy failover.""" def custom_exc_filter(exc): return isinstance(exc, NotImplementedError) def fake_request(method, url, proxies=None, **kwargs): if proxies and proxies['http'] == 'http://a:80': raise NotImplementedError() sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80'), exception_proxy_fail_filter=custom_exc_filter) with _patch_request_base(side_effect=fake_request) as request: sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_failover_using_custom_exception_criteria(self): """Use a custom request exception filter to say that some arbitrary exception is considered a proxy failure, in order to trigger proxy failover.""" def custom_exc_filter(exc): return isinstance(exc, NotImplementedError) def fake_request(method, url, proxies=None, **kwargs): if proxies and proxies['http'] == 'http://a:80': raise NotImplementedError() sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80; PROXY b:80'), exception_proxy_fail_filter=custom_exc_filter) with _patch_request_base(side_effect=fake_request) as request: sess.get(arbitrary_url) request.assert_has_calls([ get_call(arbitrary_url, 'http://a:80'), get_call(arbitrary_url, 'http://b:80'), ])
def test_post_init_proxy_auth(self): """Set proxy auth info after constructing PACSession, and ensure that PAC proxy URLs then reflect it.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80;')) with _patch_request_base() as request: sess.get(arbitrary_url) # Prime proxy resolver state. request.assert_has_calls([ get_call(arbitrary_url, 'http://*****:*****@a:80'), ])
def test_post_init_proxy_auth(self): """Set proxy auth info after constructing PACSession, and ensure that PAC proxy URLs then reflect it.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY a:80;')) with _patch_request_base() as request: sess.get(arbitrary_url) # Prime proxy resolver state. request.assert_has_calls([ get_call(arbitrary_url, 'http://*****:*****@a:80'), ])
def test_bad_proxy_no_failover(self): """Verify that Requests returns ProxyError when given a non-existent proxy.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % "PROXY httpbin.org:99")) with pytest.raises((ProxyError, ConnectTimeout)): sess.get(arbitrary_url, timeout=1)
def test_no_pac_but_call_get_pac_twice(self): with _patch_get_pac(None): sess = PACSession() for _ in range(2): assert sess.get_pac() is None
def test_bad_proxy_no_failover(self, proxy_host): """Verify that Requests returns ProxyError when given a non-existent proxy.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY %s:80' % proxy_host)) with pytest.raises(ProxyError): sess.get(arbitrary_url)
def test_pac_from_constructor(self): sess = PACSession(pac=PACFile(direct_pac_js)) for _ in range(2): assert sess.get_pac() is not None
def test_bad_proxy_no_failover(self, proxy_host): """Verify that Requests returns ProxyError when given a non-existent proxy.""" sess = PACSession(pac=PACFile(proxy_pac_js_tpl % 'PROXY %s:80' % proxy_host)) with pytest.raises(ProxyError): sess.get(arbitrary_url)
def test_pac_from_constructor(self): sess = PACSession(pac=PACFile(direct_pac_js)) for _ in range(2): assert sess.get_pac() is not None
def test_no_pac_but_call_get_pac_twice(self): with _patch_get_pac(None): sess = PACSession() for _ in range(2): assert sess.get_pac() is None