Browse Source

fix: constistent behavior for `HTTPS_METHOD=nohttp`

Without this fix the response of nohttp sites to HTTP requests changes
depending on the existence of at least one HTTP enabled site:
* no HTTP enabled sites -> connection refused
* at least one HTTP enabled site -> 503

This fix ensures the response is always 503.
Gilles Filippini 1 năm trước cách đây
mục cha
commit
91652aac48
3 tập tin đã thay đổi với 10 bổ sung13 xóa
  1. 1 2
      nginx.tmpl
  2. 5 7
      test/test_fallback.py
  3. 4 4
      test/test_ssl/test_nohttp.py

+ 1 - 2
nginx.tmpl

@@ -650,7 +650,7 @@ proxy_set_header Proxy "";
         {{- $default_https_exists = or $default_https_exists (and $https $vhost.default) }}
         {{- $http3_enabled = or $http3_enabled $vhost.http3_enabled }}
     {{- end }}
-    {{- $fallback_http := and $http_exists (not $default_http_exists) }}
+    {{- $fallback_http := not $default_http_exists }}
     {{- $fallback_https := and $https_exists (not $default_https_exists) }}
     {{- /*
          * If there are no vhosts at all, create fallbacks for both plain http
@@ -658,7 +658,6 @@ proxy_set_header Proxy "";
          * refused error.
          */}}
     {{- if and (not $http_exists) (not $https_exists) }}
-        {{- $fallback_http = true }}
         {{- $fallback_https = true }}
     {{- end }}
     {{- if or $fallback_http $fallback_https }}

+ 5 - 7
test/test_fallback.py

@@ -60,19 +60,17 @@ CONNECTION_REFUSED_RE = re.compile("Connection refused")
     ("nodefault.yml", "http://unknown.nginx-proxy.test/", 503, None),
     ("nodefault.yml", "https://unknown.nginx-proxy.test/", None, INTERNAL_ERR_RE),
     # HTTPS_METHOD=nohttp on nginx-proxy, HTTPS_METHOD unset on the app container.
-    ("nohttp.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
+    ("nohttp.yml", "http://https-only.nginx-proxy.test/", 503, None),
     ("nohttp.yml", "https://https-only.nginx-proxy.test/", 200, None),
-    ("nohttp.yml", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
+    ("nohttp.yml", "http://unknown.nginx-proxy.test/", 503, None),
     ("nohttp.yml", "https://unknown.nginx-proxy.test/", 503, None),
     # HTTPS_METHOD=redirect on nginx-proxy, HTTPS_METHOD=nohttp on the app container.
-    ("nohttp-on-app.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
+    ("nohttp-on-app.yml", "http://https-only.nginx-proxy.test/", 503, None),
     ("nohttp-on-app.yml", "https://https-only.nginx-proxy.test/", 200, None),
-    ("nohttp-on-app.yml", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
+    ("nohttp-on-app.yml", "http://unknown.nginx-proxy.test/", 503, None),
     ("nohttp-on-app.yml", "https://unknown.nginx-proxy.test/", 503, None),
     # Same as nohttp.yml, except there is a vhost with a missing cert.  This causes its
-    # HTTPS_METHOD=nohttp setting to effectively become HTTPS_METHOD=noredirect.  This means that
-    # there will be a plain http server solely to support that vhost, so http requests to other
-    # vhosts get a 503, not a connection refused error.
+    # HTTPS_METHOD=nohttp setting to effectively become HTTPS_METHOD=noredirect.
     ("nohttp-with-missing-cert.yml", "http://https-only.nginx-proxy.test/", 503, None),
     ("nohttp-with-missing-cert.yml", "https://https-only.nginx-proxy.test/", 200, None),
     ("nohttp-with-missing-cert.yml", "http://missing-cert.nginx-proxy.test/", 200, None),

+ 4 - 4
test/test_ssl/test_nohttp.py

@@ -3,15 +3,15 @@ import requests
 
 
 def test_web2_http_is_connection_refused(docker_compose, nginxproxy):
-    with pytest.raises(requests.exceptions.RequestException, match="Connection refused"):
-        nginxproxy.get("http://web2.nginx-proxy.tld/")
+    r = nginxproxy.get("http://web2.nginx-proxy.tld/", allow_redirects=False)
+    assert r.status_code == 503
 
 
 def test_web2_http_is_connection_refused_for_acme_challenge(
     docker_compose, nginxproxy, acme_challenge_path
 ):
-    with pytest.raises(requests.exceptions.RequestException, match="Connection refused"):
-        nginxproxy.get(f"http://web2.nginx-proxy.tld/{acme_challenge_path}")
+    r = nginxproxy.get(f"http://web2.nginx-proxy.tld/{acme_challenge_path}", allow_redirects=False)
+    assert r.status_code == 503
 
 
 def test_web2_https_is_forwarded(docker_compose, nginxproxy):