echo-client-hints-received.py (2640B)
1 """ Handle the initiator navigation request and attach the received client info 2 to the returned page. 3 """ 4 5 6 import textwrap 7 8 html_template = """ 9 <!DOCTYPE html> 10 <html> 11 <head> 12 <title>echo client hints on prerendering page</title> 13 </head> 14 <script src="/speculation-rules/prerender/resources/utils.js"></script> 15 <body> 16 <script> 17 18 // Allow generator to add the received CH information into this script. 19 %s 20 const params = new URLSearchParams(location.search); 21 const uid = params.get('uid'); 22 23 // Performs the check below on initiator pages: 24 // 1. The client did not send server_received_full_version_list when fetching 25 // the initiator page. 26 // If the check fails, it will ask the main test page to terminate the test. 27 // Otherwise, it will: 28 // 1. Initiate a prerendering action. And the prerendering page will perform 29 // some checks. 30 // 2. Wait for the prerendering page to pass all checks and send a signal back. 31 // 3. Activate the prerendered page. 32 async function load_as_initiator_page() { 33 if (!server_received_bitness || server_received_full_version_list) { 34 // The initial headers are not as expected. Terminate the test. 35 failTest( 36 `unexpected initial headers. 37 bitness: ${server_received_bitness}, 38 full_version: ${server_received_full_version_list}`, 39 uid); 40 return; 41 } 42 const prerendering_url = 43 `./echo-prerender-page-client-hints-received.py?uid=${uid}`; 44 // Wait for the prerendered page to be ready for activation. 45 const bc = new PrerenderChannel('prerender-channel', uid); 46 const gotMessage = new Promise(resolve => { 47 bc.addEventListener('message', e => { 48 resolve(e.data); 49 }, {once: true}); 50 }); 51 startPrerendering(prerendering_url); 52 53 data = await gotMessage; 54 if (data == 'ready for activation') { 55 window.location = prerendering_url; 56 } else { 57 failTest(`Initial page received unexpected result: ${data}`, uid); 58 } 59 } 60 61 load_as_initiator_page(); 62 63 </script> 64 </body> 65 </html> 66 """ 67 68 def translate_to_js(val: bool) -> str: 69 if isinstance(val, bool): 70 return "true" if val else "false" 71 return "" 72 73 def main(request, response): 74 response.status = 200 75 76 # Insert the received hints into script. 77 content = html_template % ( 78 textwrap.dedent( 79 f""" 80 const server_received_bitness = 81 {translate_to_js(b"sec-ch-ua-bitness" in request.headers)}; 82 const server_received_full_version_list = 83 {translate_to_js(b"sec-ch-ua-full-version-list" in 84 request.headers)}; 85 """ 86 ) 87 ) 88 response.content = content.encode("utf-8")