diff --git a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py index c07586d8c..928870f66 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py +++ b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py @@ -177,8 +177,15 @@ def test_enhancements(plugin, domains): "enhancements") return False - for domain in domains: + domains_and_info = [(domain, []) for domain in domains] + + for domain, info in domains_and_info: try: + verify = functools.partial(validator.Validator().any_redirect, + "localhost", plugin.http_port, + headers={"Host": domain}) + previous_redirect = _try_until_true(verify) + info.append(previous_redirect) plugin.enhance(domain, "redirect") plugin.save() # Needed by the Apache plugin except le_errors.PluginError as error: @@ -194,12 +201,14 @@ def test_enhancements(plugin, domains): return False success = True - for domain in domains: - verify = functools.partial(validator.Validator().redirect, "localhost", - plugin.http_port, headers={"Host": domain}) - if not _try_until_true(verify): - logger.error("*** Improper redirect for domain %s", domain) - success = False + for domain, info in domains_and_info: + previous_redirect = info[0] + if not previous_redirect: + verify = functools.partial(validator.Validator().redirect, "localhost", + plugin.http_port, headers={"Host": domain}) + if not _try_until_true(verify): + logger.error("*** Improper redirect for domain %s", domain) + success = False if success: logger.info("Enhancements test succeeded") diff --git a/certbot-compatibility-test/certbot_compatibility_test/validator.py b/certbot-compatibility-test/certbot_compatibility_test/validator.py index 62dd466a1..0fd6efab5 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/validator.py +++ b/certbot-compatibility-test/certbot_compatibility_test/validator.py @@ -45,19 +45,12 @@ class Validator(object): else: response = requests.get(url, allow_redirects=False) - if response.status_code not in (301, 303): - return False - redirect_location = response.headers.get("location", "") # We're checking that the redirect we added behaves correctly. # It's okay for some server configuration to redirect to an # http URL, as long as it's on some other domain. if not redirect_location.startswith("https://"): - if not redirect_location.startswith("http://"): - return False - else: - if redirect_location[len("http://"):] == name: - return False + return False if response.status_code != 301: logger.error("Server did not redirect with permanent code") @@ -65,6 +58,16 @@ class Validator(object): return True + def any_redirect(self, name, port=80, headers=None): + """Test whether webserver redirects.""" + url = "http://{0}:{1}".format(name, port) + if headers: + response = requests.get(url, headers=headers, allow_redirects=False) + else: + response = requests.get(url, allow_redirects=False) + + return response.status_code in xrange(300, 309) + def hsts(self, name): """Test for HTTP Strict Transport Security header""" headers = requests.get("https://" + name).headers diff --git a/tox.ini b/tox.ini index 5d6de5730..39218651c 100644 --- a/tox.ini +++ b/tox.ini @@ -151,7 +151,7 @@ passenv = DOCKER_* commands = docker build -t certbot-compatibility-test -f certbot-compatibility-test/Dockerfile . docker build -t nginx-compat -f certbot-compatibility-test/Dockerfile-nginx . - docker run --rm -it nginx-compat -c nginx.tar.gz -vvvv -ai + docker run --rm -it nginx-compat -c nginx.tar.gz -vvvv -aie whitelist_externals = docker passenv = DOCKER_*