sjs_early-hint-test-server.sjs (1846B)
1 "use strict"; 2 3 function handleRequest(request, response) { 4 // write to raw socket 5 response.seizePower(); 6 7 const qs = new URLSearchParams(request.queryString); 8 const imgs = []; 9 let new_hint = true; 10 let new_header = true; 11 for (const [imgUrl, uuid] of qs.entries()) { 12 if (new_hint) { 13 // we need to write a new header 14 new_hint = false; 15 response.write("HTTP/1.1 103 Early Hint\r\n"); 16 } 17 if (!imgUrl.length) { 18 // next hint in new early hint response when empty string is passed 19 new_header = true; 20 if (uuid === "new_response") { 21 new_hint = true; 22 response.write("\r\n"); 23 } else if (uuid === "non_link_header") { 24 response.write("Content-Length: 25\r\n"); 25 } 26 response.write("\r\n"); 27 } else { 28 // either append link in new header or in same header 29 if (new_header) { 30 new_header = false; 31 response.write("Link: "); 32 } else { 33 response.write(", "); 34 } 35 // add query string to make request unique this has the drawback that 36 // the preloaded image can't accept query strings on it's own / or has 37 // to strip the appended "?uuid" from the query string before parsing 38 imgs.push(`<img src="${imgUrl}?${uuid}" width="100px">`); 39 response.write(`<${imgUrl}?${uuid}>; rel=preload; as=image`); 40 } 41 } 42 if (!new_hint) { 43 // add separator to main document 44 response.write("\r\n\r\n"); 45 } 46 47 const body = `<!DOCTYPE html> 48 <html> 49 <body> 50 ${imgs.join("\n")} 51 </body> 52 </html>`; 53 54 // main document response 55 response.write("HTTP/1.1 200 OK\r\n"); 56 response.write("Content-Type: text/html;charset=utf-8\r\n"); 57 response.write("Cache-Control: no-cache\r\n"); 58 response.write(`Content-Length: ${body.length}\r\n`); 59 response.write("\r\n"); 60 response.write(body); 61 response.finish(); 62 }