about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2020-01-02 21:41:48 +0100
committeraszlig <aszlig@nix.build>2020-01-02 21:41:59 +0100
commit845e92835d90d300142157c6bae9ca5b7831e2bd (patch)
tree527a5847441933e7cf8a61c253f08abbbe0e19f1 /nixos
parent129c73802fdddacb20cf194bd2968d73ebced590 (diff)
parentccf55bead1f3bc2a6419a9fdcec55933ffe046de (diff)
downloadnixlib-845e92835d90d300142157c6bae9ca5b7831e2bd.tar
nixlib-845e92835d90d300142157c6bae9ca5b7831e2bd.tar.gz
nixlib-845e92835d90d300142157c6bae9ca5b7831e2bd.tar.bz2
nixlib-845e92835d90d300142157c6bae9ca5b7831e2bd.tar.lz
nixlib-845e92835d90d300142157c6bae9ca5b7831e2bd.tar.xz
nixlib-845e92835d90d300142157c6bae9ca5b7831e2bd.tar.zst
nixlib-845e92835d90d300142157c6bae9ca5b7831e2bd.zip
Merge Last-Modified fix for nginx (#76697)
This fixes the patch for nginx to clear the Last-Modified header if a
static file is served from the Nix store.

So far we only used the ETag from the store path, but if the
Last-Modified header is always set to "Thu, 01 Jan 1970 00:00:01 GMT",
Firefox and Chrome/Chromium seem to ignore the ETag and simply use the
cached content instead of revalidating.

Alongside the fix, this also adds a dedicated NixOS VM test, which uses
WebDriver and Firefox to check whether the content is actually served
from the browser's cache and to have a more real-world test case.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/nginx-etag.nix89
2 files changed, 90 insertions, 0 deletions
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 0bbf0d9ab416..3f6921e0f4dd 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -198,6 +198,7 @@ in
   nfs4 = handleTest ./nfs { version = 4; };
   nghttpx = handleTest ./nghttpx.nix {};
   nginx = handleTest ./nginx.nix {};
+  nginx-etag = handleTest ./nginx-etag.nix {};
   nginx-sso = handleTest ./nginx-sso.nix {};
   nix-ssh-serve = handleTest ./nix-ssh-serve.nix {};
   nixos-generate-config = handleTest ./nixos-generate-config.nix {};
diff --git a/nixos/tests/nginx-etag.nix b/nixos/tests/nginx-etag.nix
new file mode 100644
index 000000000000..e357309d166a
--- /dev/null
+++ b/nixos/tests/nginx-etag.nix
@@ -0,0 +1,89 @@
+import ./make-test-python.nix {
+  name = "nginx-etag";
+
+  nodes = {
+    server = { pkgs, lib, ... }: {
+      networking.firewall.enable = false;
+      services.nginx.enable = true;
+      services.nginx.virtualHosts.server = {
+        root = pkgs.runCommandLocal "testdir" {} ''
+          mkdir "$out"
+          cat > "$out/test.js" <<EOF
+          document.getElementById('foobar').setAttribute('foo', 'bar');
+          EOF
+          cat > "$out/index.html" <<EOF
+          <!DOCTYPE html>
+          <div id="foobar">test</div>
+          <script src="test.js"></script>
+          EOF
+        '';
+      };
+
+      nesting.clone = lib.singleton {
+        services.nginx.virtualHosts.server = {
+          root = lib.mkForce (pkgs.runCommandLocal "testdir2" {} ''
+            mkdir "$out"
+            cat > "$out/test.js" <<EOF
+            document.getElementById('foobar').setAttribute('foo', 'yay');
+            EOF
+            cat > "$out/index.html" <<EOF
+            <!DOCTYPE html>
+            <div id="foobar">test</div>
+            <script src="test.js"></script>
+            EOF
+          '');
+        };
+      };
+    };
+
+    client = { pkgs, lib, ... }: {
+      virtualisation.memorySize = 512;
+      environment.systemPackages = let
+        testRunner = pkgs.writers.writePython3Bin "test-runner" {
+          libraries = [ pkgs.python3Packages.selenium ];
+        } ''
+          import os
+          import time
+
+          from selenium.webdriver import Firefox
+          from selenium.webdriver.firefox.options import Options
+
+          options = Options()
+          options.add_argument('--headless')
+          driver = Firefox(options=options)
+
+          driver.implicitly_wait(20)
+          driver.get('http://server/')
+          driver.find_element_by_xpath('//div[@foo="bar"]')
+          open('/tmp/passed_stage1', 'w')
+
+          while not os.path.exists('/tmp/proceed'):
+              time.sleep(0.5)
+
+          driver.get('http://server/')
+          driver.find_element_by_xpath('//div[@foo="yay"]')
+          open('/tmp/passed', 'w')
+        '';
+      in [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ];
+    };
+  };
+
+  testScript = { nodes, ... }: let
+    inherit (nodes.server.config.system.build) toplevel;
+    newSystem = "${toplevel}/fine-tune/child-1";
+  in ''
+    start_all()
+
+    server.wait_for_unit("nginx.service")
+    client.wait_for_unit("multi-user.target")
+    client.execute("test-runner &")
+    client.wait_for_file("/tmp/passed_stage1")
+
+    server.succeed(
+        "${newSystem}/bin/switch-to-configuration test >&2"
+    )
+    client.succeed("touch /tmp/proceed")
+
+    client.wait_for_file("/tmp/passed")
+  '';
+}