Selaa lähdekoodia

Self-host the httpbin auth-testing backend for BaseAuthTest/DigestAuthTest

These tests exercise the squid proxies by hitting /basic-auth and
/digest-auth on an external httpbin-style site. That site's identity has
already moved twice (httpbin.org -> httpcan.org, per #2300) chasing
uptime, and httpcan.org itself is now down (Cloudflare 502 from its
origin), failing CI with no code change involved.

Adds two containers to the existing squid docker-compose stack instead:
go-httpbin (mccutchen/go-httpbin) as the backend, and an nginx sidecar in
front of it under the single "httpbin" hostname so both the NoSSL tests
(port 80) and the SSL tests, which CONNECT-tunnel through the proxy to
port 443, resolve the same name -- go-httpbin only listens on one port at
a time, so it can't serve both protocols itself. nginx uses the repo's
existing self-signed test cert; the SSL client tests already disable
verification for it like other self-signed-cert tests in this suite.

go-httpbin was picked over the more feature-complete kennethreitz/httpbin
after finding the latter accepts a wrong digest-auth username as long as
the password matches -- confirmed with a direct curl against the
container, unrelated to anything in this repo. go-httpbin correctly
rejects both. The trade-off is losing SHA-512 digest-auth coverage here,
since go-httpbin only implements MD5 and SHA-256; nothing else in the
suite exercises SHA-512 digest auth against a live server. Response body
assertions are adjusted to go-httpbin's actual JSON shape (an added
"authorized" field, no "algorithm" field), and the domain changes from
httpcan.org to the self-hosted "httpbin".

This only affects 'make proxy'/'make proxy_mbedtls'/'make proxy_wolfssl'
and the Proxy Test CI workflow -- the default 'make' target is untouched.
yhirose 1 kuukausi sitten
vanhempi
commit
88956ccad8
3 muutettua tiedostoa jossa 59 lisäystä ja 12 poistoa
  1. 21 0
      test/proxy/docker-compose.yml
  2. 22 0
      test/proxy/httpbin_nginx.conf
  3. 16 12
      test/test_proxy.cc

+ 21 - 0
test/proxy/docker-compose.yml

@@ -18,3 +18,24 @@ services:
       context: ./
       args:
         auth: digest
+
+  # Self-hosted stand-in for the httpbin.org-style auth-testing endpoints
+  # (/basic-auth, /digest-auth) that BaseAuthTest/DigestAuthTest exercise
+  # through the proxies above, so those tests don't depend on an external
+  # site's uptime.
+  httpbin_backend:
+    image: mccutchen/go-httpbin:latest
+    restart: always
+
+  # TLS termination in front of httpbin_backend (which only speaks plain
+  # HTTP) so the SSL variants of those tests can CONNECT-tunnel through the
+  # proxies to "httpbin" on port 443, same as the NoSSL variants do on 80.
+  httpbin:
+    image: nginx:alpine
+    restart: always
+    depends_on:
+      - httpbin_backend
+    volumes:
+      - ./httpbin_nginx.conf:/etc/nginx/conf.d/default.conf:ro
+      - ../cert.pem:/etc/nginx/certs/cert.pem:ro
+      - ../key.pem:/etc/nginx/certs/key.pem:ro

+ 22 - 0
test/proxy/httpbin_nginx.conf

@@ -0,0 +1,22 @@
+server {
+    listen 80;
+    server_name httpbin;
+
+    location / {
+        proxy_pass http://httpbin_backend:8080;
+        proxy_set_header Host $host;
+    }
+}
+
+server {
+    listen 443 ssl;
+    server_name httpbin;
+
+    ssl_certificate /etc/nginx/certs/cert.pem;
+    ssl_certificate_key /etc/nginx/certs/key.pem;
+
+    location / {
+        proxy_pass http://httpbin_backend:8080;
+        proxy_set_header Host $host;
+    }
+}

+ 16 - 12
test/test_proxy.cc

@@ -173,7 +173,8 @@ template <typename T> void BaseAuthTestFromHTTPWatch(T &cli) {
         cli.Get("/basic-auth/hello/world",
                 Headers{make_basic_authentication_header("hello", "world")});
     ASSERT_TRUE(res != nullptr);
-    EXPECT_EQ(normalizeJson("{\"authenticated\":true,\"user\":\"hello\"}\n"),
+    EXPECT_EQ(normalizeJson("{\"authenticated\":true,\"user\":\"hello\","
+                            "\"authorized\":true}\n"),
               normalizeJson(res->body));
     EXPECT_EQ(StatusCode::OK_200, res->status);
   }
@@ -182,7 +183,8 @@ template <typename T> void BaseAuthTestFromHTTPWatch(T &cli) {
     cli.set_basic_auth("hello", "world");
     auto res = cli.Get("/basic-auth/hello/world");
     ASSERT_TRUE(res != nullptr);
-    EXPECT_EQ(normalizeJson("{\"authenticated\":true,\"user\":\"hello\"}\n"),
+    EXPECT_EQ(normalizeJson("{\"authenticated\":true,\"user\":\"hello\","
+                            "\"authorized\":true}\n"),
               normalizeJson(res->body));
     EXPECT_EQ(StatusCode::OK_200, res->status);
   }
@@ -203,13 +205,14 @@ template <typename T> void BaseAuthTestFromHTTPWatch(T &cli) {
 }
 
 TEST(BaseAuthTest, NoSSL) {
-  Client cli("httpcan.org");
+  Client cli("httpbin");
   BaseAuthTestFromHTTPWatch(cli);
 }
 
 #ifdef CPPHTTPLIB_SSL_ENABLED
 TEST(BaseAuthTest, SSL) {
-  SSLClient cli("httpcan.org");
+  SSLClient cli("httpbin");
+  cli.enable_server_certificate_verification(false);
   BaseAuthTestFromHTTPWatch(cli);
 }
 #endif
@@ -228,21 +231,21 @@ template <typename T> void DigestAuthTestFromHTTPWatch(T &cli) {
   }
 
   {
+    // go-httpbin (the "httpbin" test double) only implements MD5 and
+    // SHA-256 for digest auth, so SHA-256 is as far as this can exercise
+    // the client's digest-auth algorithm selection end-to-end.
     std::vector<std::string> paths = {
         "/digest-auth/auth/hello/world/MD5",
         "/digest-auth/auth/hello/world/SHA-256",
-        "/digest-auth/auth/hello/world/SHA-512",
     };
 
     cli.set_digest_auth("hello", "world");
     for (auto path : paths) {
       auto res = cli.Get(path.c_str());
       ASSERT_TRUE(res != nullptr);
-      std::string algo(path.substr(path.rfind('/') + 1));
-      EXPECT_EQ(
-          normalizeJson("{\"algorithm\":\"" + algo +
-                        "\",\"authenticated\":true,\"user\":\"hello\"}\n"),
-          normalizeJson(res->body));
+      EXPECT_EQ(normalizeJson("{\"authenticated\":true,\"user\":\"hello\","
+                              "\"authorized\":true}\n"),
+                normalizeJson(res->body));
       EXPECT_EQ(StatusCode::OK_200, res->status);
     }
 
@@ -263,12 +266,13 @@ template <typename T> void DigestAuthTestFromHTTPWatch(T &cli) {
 }
 
 TEST(DigestAuthTest, SSL) {
-  SSLClient cli("httpcan.org");
+  SSLClient cli("httpbin");
+  cli.enable_server_certificate_verification(false);
   DigestAuthTestFromHTTPWatch(cli);
 }
 
 TEST(DigestAuthTest, NoSSL) {
-  Client cli("httpcan.org");
+  Client cli("httpbin");
   DigestAuthTestFromHTTPWatch(cli);
 }
 #endif