summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/fetch/http-cache/split-cache.html
blob: fe93d2e3400e9cba5390d0a3a0cae7ff64f4907f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>HTTP Cache - Partioning by site</title>
  <meta name="help" href="https://fetch.spec.whatwg.org/#http-cache-partitions">
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
  <script src="/common/utils.js"></script>
  <script src="/common/get-host-info.sub.js"></script>
  <script src="http-cache.js"></script>
</head>
<body>
<script>
const host = get_host_info();

// We run this entire test four times, varying the following two booleans:
// - is_cross_site_test, which controls whether the popup is cross-site.
// - load_resource_in_iframe, which controls whether the popup loads the
//     resource in an iframe or the top-level frame. Note that the iframe is
//     always same-site to the opener.
function performFullTest(is_cross_site_test, load_resource_in_iframe, name) {
  const POPUP_HTTP_ORIGIN = is_cross_site_test ? host.HTTP_NOTSAMESITE_ORIGIN : host.HTTP_ORIGIN
  const LOCAL_HTTP_ORIGIN = host.HTTP_ORIGIN

  const popupBaseURL = POPUP_HTTP_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;
  const localBaseURL = LOCAL_HTTP_ORIGIN + window.location.pathname.replace(/\/[^\/]*$/, '/') ;

  // Note: Navigation requests are requested with credentials. Make sure the
  // fetch requests are also requested with credentials. This ensures passing
  // this test is not simply the consequence of discriminating anonymous and
  // credentialled request in the HTTP cache.
  //
  // See https://github.com/whatwg/fetch/issues/1253
  var test = {
    requests: [
      {
        response_headers: [
          ["Expires", (30 * 24 * 60 * 60)],
          ["Access-Control-Allow-Origin", POPUP_HTTP_ORIGIN],
        ],
        base_url: localBaseURL,
        credentials: "include",
      },
      {
        response_headers: [
          ["Access-Control-Allow-Origin", POPUP_HTTP_ORIGIN],
        ],
        base_url: localBaseURL,
        credentials: "include",
      },
      {
        request_headers: [
          ["Cache-Control", "no-cache"]
        ],
        response_headers: [
          ["Access-Control-Allow-Origin", POPUP_HTTP_ORIGIN],
        ],
        // If the popup's request was a cache hit, we would only expect 2
        // requests to the server. If it was a cache miss, we would expect 3.
        // load_resource_in_iframe does not affect the expectation as, even
        // though the iframe (if present) is same-site, we expect a cache miss
        // when the popup's top-level frame is a different site.
        expected_response_headers: [
          ["server-request-count", is_cross_site_test ? "3" : "2"]
        ],
        base_url: localBaseURL,
        credentials: "include",
      }
    ]
  }

  var uuid = token()
  var local_requests = expandTemplates(test)
  var fetchFns = makeFetchFunctions(local_requests, uuid)

  var popup_requests = expandTemplates(test)

  // Request the resource with a long cache expiry
  function local_fetch() {
    return fetchFns[0].code(0)
  }

  function popup_fetch() {
    return new Promise(function(resolve, reject) {
      var relativeUrl = load_resource_in_iframe
          ? "resources/split-cache-popup-with-iframe.html"
          : "resources/split-cache-popup.html";
      var win = window.open(popupBaseURL + relativeUrl);

      // Post a message to initiate the popup's request and give the necessary
      // information. Posted repeatedly to account for dropped messages as the
      // popup is loading.
      function postMessage(event) {
        var payload = {
          index: 1,
          requests: popup_requests,
          uuid: uuid
        }
        win.postMessage(payload, POPUP_HTTP_ORIGIN)
      }
      var messagePoster = setInterval(postMessage, 100)

      // Listen for the result
      function messageListener(event) {
        if (event.origin !== POPUP_HTTP_ORIGIN) {
          reject("Unknown error")
        } else if (event.data === "success") {
          resolve()
        } else if (event.data === "error") {
          reject("Error in popup")
        } else {
          return; // Ignore testharness.js internal messages
        }
        window.removeEventListener("message", messageListener)
        clearInterval(messagePoster)
        win.close()
      }
      window.addEventListener("message", messageListener)
    })
  }

  function local_fetch2() {
    return fetchFns[2].code(2)
  }

  // Final checks.
  function check_server_info() {
    return getServerState(uuid)
      .then(function (testState) {
        checkRequests(local_requests, testState)
        return Promise.resolve()
      })
  }

  promise_test(() => {
    return local_fetch()
      .then(popup_fetch)
      .then(local_fetch2)
      .then(check_server_info)
  }, name)
}

performFullTest(
  false /* is_cross_site_test */, false /* load_resource_in_iframe */,
  "HTTP cache is shared between same-site top-level frames");
performFullTest(
  true /* is_cross_site_test */, false /* load_resource_in_iframe */,
  "HTTP cache is not shared between cross-site top-level frames");
performFullTest(
  false /* is_cross_site_test */, true /* load_resource_in_iframe */,
  "HTTP cache is shared between same-site frames with same-site top-level frames");
performFullTest(
  true /* is_cross_site_test */, true /* load_resource_in_iframe */,
  "HTTP cache is not shared between same-site frames with cross-site top-level frames");
</script>
</body>
</html>