| 12
 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
 
 | """ Handle the prerendering navigation request and insert the received client
info to the returned page.
"""
import textwrap
html_template = """
<!DOCTYPE html>
<html>
<head>
<title>echo client hints on prerendering page</title>
</head>
<script src="/speculation-rules/prerender/resources/utils.js"></script>
<body>
<script>
// Allow generator to add the received CH information into this script.
%s
const params = new URLSearchParams(location.search);
const uid = params.get('uid');
// Performs the following checks on prerendering pages:
// 1. The client did not send server_received_full_version_list when fetching
//    the prerendering main resource.
// 2. The request initiated by the prerendering page is sent with
//    sec-ch-ua-full-version-list attached, because the server asked the
//    prerendering page to attach this hint for the following requests.
// If any of the checks fails, it will ask the main test page to terminate
// the test.
// Otherwise, it asks the initiator page to perform activation, and informs
// the main test page of the test success upon being activated. This is used
// to verify that the initiator page's client hints cache is not modified by
// the prerendering page, i.e., the initiator page does not attach
// sec-ch-ua-full-version-list to the requests.
async function load_as_prerendering_page() {
  // The first prerendering request should not contain the field of
  // sec-ch-ua-full-version-list, as prerender is initiated by the initial
  // page.
  if (!server_received_bitness || server_received_full_version_list) {
    failTest(
        `Prerender page saw unexpected request headers.
             bitness: ${server_received_bitness},
             full_version: ${server_received_full_version_list}`,
        uid);
  }
  const r =
      await fetch('../resources/echo-subresource-client-hints-received.py');
  if (r.status != 200 || r.headers.get('server_received_bitness') !== 'true' ||
      r.headers.get('server_received_full_version_list') !== 'true') {
    failTest(
        `Prerender page saw unexpected headers while fetching
             sub-resources.
             bitness: ${r.headers.get('server_received_bitness')},
             full_version: ${
            r.headers.get('server_received_full_version_list')}`,
        uid);
  } else {
    document.onprerenderingchange = () => {
      const bc = new PrerenderChannel('test-channel', uid);
      // Send the result to the test runner page.
      bc.postMessage({result: 'PASSED'});
    };
    const bc = new PrerenderChannel('prerender-channel', uid);
    bc.postMessage('ready for activation');
  }
}
load_as_prerendering_page();
</script>
</body>
</html>
"""
def translate_to_js(val: bool) -> str:
    if isinstance(val, bool):
        return "true" if val else "false"
    return ""
def main(request, response):
    response.headers.set(b"Accept-CH", "sec-ch-ua-full-version-list")
    response.status = 200
    # Insert the received hints into script.
    content = html_template % (
        textwrap.dedent(
            f"""
            const server_received_bitness =
                {translate_to_js(b"sec-ch-ua-bitness" in request.headers)};
            const server_received_full_version_list =
                {translate_to_js(b"sec-ch-ua-full-version-list" in
                    request.headers)};
            """
        )
    )
    response.content = content.encode("utf-8")
 |