aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/__init__.py5
-rw-r--r--tests/test_external.py31
-rw-r--r--tests/test_http.py37
-rw-r--r--tests/test_proxy.py29
4 files changed, 98 insertions, 4 deletions
diff --git a/tests/__init__.py b/tests/__init__.py
index 69d7d10..28959d3 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -269,7 +269,8 @@ def server_socket(fun, request_count=1, timeout=5):
gcounter[0] += 1
keep = True
keep &= gcounter[0] < request_count
- keep &= request.headers.get("connection", "").lower() != "close"
+ if request is not None:
+ keep &= request.headers.get("connection", "").lower() != "close"
return keep
def server_socket_thread(srv):
@@ -295,7 +296,7 @@ def server_socket(fun, request_count=1, timeout=5):
)
except Exception as e:
# traceback.print_exc caused IOError: concurrent operation on sys.stderr.close() under setup.py test
- sys.stderr.write(traceback.format_exc().encode())
+ print(traceback.format_exc(), file=sys.stderr)
gresult[0] = e
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
diff --git a/tests/test_external.py b/tests/test_external.py
index 10b0d8b..0628d96 100644
--- a/tests/test_external.py
+++ b/tests/test_external.py
@@ -96,3 +96,34 @@ def test_sni_hostname_validation():
# TODO: make explicit test server with SNI validation
http = httplib2.Http()
http.request("https://google.com/", method="GET")
+
+
+@pytest.mark.skipif(
+ os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"),
+ reason="Python 2.7 doesn't support TLS min/max"
+)
+def test_min_tls_version():
+ # skip on Python versions that don't support TLS min
+ if not hasattr(ssl.SSLContext(), 'minimum_version'):
+ return
+ # BadSSL server that supports max TLS 1.1,
+ # forcing 1.2 should always fail
+ http = httplib2.Http(tls_minimum_version="TLSv1_2")
+ with tests.assert_raises(ssl.SSLError):
+ http.request("https://tls-v1-1.badssl.com:1011/")
+
+
+@pytest.mark.skipif(
+ os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"),
+ reason="Python 2.7 doesn't support TLS min/max"
+)
+def test_max_tls_version():
+ # skip on Python versions that don't support TLS max
+ if not hasattr(ssl.SSLContext(), 'maximum_version'):
+ return
+ # Google supports TLS 1.2+, confirm we can force down to 1.0
+ # this may break whenever Google disables TLSv1
+ http = httplib2.Http(tls_maximum_version="TLSv1")
+ http.request("https://google.com")
+ _, tls_ver, _ = http.connections['https:google.com'].sock.cipher()
+ assert tls_ver == "TLSv1.0"
diff --git a/tests/test_http.py b/tests/test_http.py
index 2bee6ca..9bd9ee0 100644
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -10,9 +10,11 @@ import os
import pytest
from six.moves import http_client, urllib
import socket
+import ssl
import tests
DUMMY_URL = "http://127.0.0.1:1"
+DUMMY_HTTPS_URL = "https://127.0.0.1:2"
def _raise_connection_refused_exception(*args, **kwargs):
@@ -645,3 +647,38 @@ content"""
assert response.status == 200
assert content == b"content"
assert response["link"], "link1, link2"
+
+
+@pytest.mark.skipif(
+ os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"),
+ reason="Python 2.7 doesn't support TLS min/max"
+)
+def test_set_min_tls_version():
+ # Test setting minimum TLS version
+ # We expect failure on Python < 3.7 or OpenSSL < 1.1
+ expect_success = hasattr(ssl.SSLContext(), 'minimum_version')
+ try:
+ http = httplib2.Http(tls_minimum_version="TLSv1_2")
+ http.request(DUMMY_HTTPS_URL)
+ except RuntimeError:
+ assert not expect_success
+ except socket.error:
+ assert expect_success
+
+
+@pytest.mark.skipif(
+ os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"),
+ reason="Python 2.7 doesn't support TLS min/max"
+)
+def test_set_max_tls_version():
+ # Test setting maximum TLS version
+ # We expect RuntimeError on Python < 3.7 or OpenSSL < 1.1
+ # We expect socket error otherwise
+ expect_success = hasattr(ssl.SSLContext(), 'maximum_version')
+ try:
+ http = httplib2.Http(tls_maximum_version="TLSv1_2")
+ http.request(DUMMY_HTTPS_URL)
+ except RuntimeError:
+ assert not expect_success
+ except socket.error:
+ assert expect_success
diff --git a/tests/test_proxy.py b/tests/test_proxy.py
index 56a7d99..375367f 100644
--- a/tests/test_proxy.py
+++ b/tests/test_proxy.py
@@ -32,8 +32,8 @@ def test_from_url_ident():
pi = httplib2.proxy_info_from_url("http://zoidberg:fish@someproxy:99")
assert pi.proxy_host == "someproxy"
assert pi.proxy_port == 99
- assert pi.proxy_user == "zoidberg"
- assert pi.proxy_pass == "fish"
+ assert pi.proxy_user == b"zoidberg"
+ assert pi.proxy_pass == b"fish"
def test_from_env():
@@ -146,3 +146,28 @@ def test_auth_str_bytes():
)
response, _ = http.request(uri, "GET")
assert response.status == 200
+
+
+def test_socks5_auth():
+ def proxy_conn(client, tick):
+ data = client.recv(64)
+ assert data == b"\x05\x02\x00\x02"
+ client.send(b"\x05\x02") # select username/password auth
+ data = client.recv(64)
+ assert data == b"\x01\x08user_str\x08pass_str"
+ client.send(b"\x01\x01") # deny
+ tick(None)
+
+ with tests.server_socket(proxy_conn) as uri:
+ uri_parsed = urllib.parse.urlparse(uri)
+ proxy_info = httplib2.ProxyInfo(
+ httplib2.socks.PROXY_TYPE_SOCKS5,
+ proxy_host=uri_parsed.hostname,
+ proxy_port=uri_parsed.port,
+ proxy_rdns=True,
+ proxy_user=u"user_str",
+ proxy_pass=u"pass_str",
+ )
+ http = httplib2.Http(proxy_info=proxy_info)
+ with tests.assert_raises(httplib2.socks.Socks5AuthError):
+ http.request(uri, "GET")