echo-prerender-page-client-hints-received.py (3418B)
1 """ Handle the prerendering navigation request and insert the received client 2 info to the returned page. 3 """ 4 5 import textwrap 6 7 html_template = """ 8 <!DOCTYPE html> 9 <html> 10 <head> 11 <title>echo client hints on prerendering page</title> 12 </head> 13 <script src="/speculation-rules/prerender/resources/utils.js"></script> 14 <body> 15 <script> 16 17 // Allow generator to add the received CH information into this script. 18 %s 19 20 const params = new URLSearchParams(location.search); 21 const uid = params.get('uid'); 22 23 // Performs the following checks on prerendering pages: 24 // 1. The client did not send server_received_full_version_list when fetching 25 // the prerendering main resource. 26 // 2. The request initiated by the prerendering page is sent with 27 // sec-ch-ua-full-version-list attached, because the server asked the 28 // prerendering page to attach this hint for the following requests. 29 // If any of the checks fails, it will ask the main test page to terminate 30 // the test. 31 // Otherwise, it asks the initiator page to perform activation, and informs 32 // the main test page of the test success upon being activated. This is used 33 // to verify that the initiator page's client hints cache is not modified by 34 // the prerendering page, i.e., the initiator page does not attach 35 // sec-ch-ua-full-version-list to the requests. 36 async function load_as_prerendering_page() { 37 // The first prerendering request should not contain the field of 38 // sec-ch-ua-full-version-list, as prerender is initiated by the initial 39 // page. 40 if (!server_received_bitness || server_received_full_version_list) { 41 failTest( 42 `Prerender page saw unexpected request headers. 43 bitness: ${server_received_bitness}, 44 full_version: ${server_received_full_version_list}`, 45 uid); 46 } 47 const r = 48 await fetch('../resources/echo-subresource-client-hints-received.py'); 49 if (r.status != 200 || r.headers.get('server_received_bitness') !== 'true' || 50 r.headers.get('server_received_full_version_list') !== 'true') { 51 failTest( 52 `Prerender page saw unexpected headers while fetching 53 sub-resources. 54 bitness: ${r.headers.get('server_received_bitness')}, 55 full_version: ${ 56 r.headers.get('server_received_full_version_list')}`, 57 uid); 58 } else { 59 document.onprerenderingchange = () => { 60 const bc = new PrerenderChannel('test-channel', uid); 61 // Send the result to the test runner page. 62 bc.postMessage({result: 'PASSED'}); 63 }; 64 const bc = new PrerenderChannel('prerender-channel', uid); 65 bc.postMessage('ready for activation'); 66 } 67 } 68 69 load_as_prerendering_page(); 70 </script> 71 </body> 72 </html> 73 """ 74 75 def translate_to_js(val: bool) -> str: 76 if isinstance(val, bool): 77 return "true" if val else "false" 78 return "" 79 80 def main(request, response): 81 response.headers.set(b"Accept-CH", "sec-ch-ua-full-version-list") 82 response.status = 200 83 84 # Insert the received hints into script. 85 content = html_template % ( 86 textwrap.dedent( 87 f""" 88 const server_received_bitness = 89 {translate_to_js(b"sec-ch-ua-bitness" in request.headers)}; 90 const server_received_full_version_list = 91 {translate_to_js(b"sec-ch-ua-full-version-list" in 92 request.headers)}; 93 """ 94 ) 95 ) 96 response.content = content.encode("utf-8")