file_service_worker_fetch_synthetic.js (2078B)
1 addEventListener("install", function (evt) { 2 evt.waitUntil(self.skipWaiting()); 3 }); 4 5 /** 6 * Given a multipart/form-data encoded string that we know to have only a single 7 * part, return the contents of the part. (MIME multipart encoding is too 8 * exciting to delve into.) 9 */ 10 function extractBlobFromMultipartFormData(text) { 11 const lines = text.split(/\r\n/g); 12 const firstBlank = lines.indexOf(""); 13 const foo = lines.slice(firstBlank + 1, -2).join("\n"); 14 return foo; 15 } 16 17 self.addEventListener("fetch", event => { 18 const url = new URL(event.request.url); 19 const mode = url.searchParams.get("mode"); 20 21 if (mode === "synthetic") { 22 event.respondWith( 23 (async () => { 24 // This works even if there wasn't a body explicitly associated with the 25 // request. We just get a zero-length string in that case. 26 const requestBodyContents = await event.request.text(); 27 const blobContents = 28 extractBlobFromMultipartFormData(requestBodyContents); 29 30 return new Response( 31 `<!DOCTYPE HTML><head><meta charset="utf-8"/></head><body> 32 <h1 id="url">${event.request.url}</h1> 33 <div id="source">ServiceWorker</div> 34 <div id="blob">${blobContents}</div> 35 </body>`, 36 { headers: { "Content-Type": "text/html" } } 37 ); 38 })() 39 ); 40 } else if (mode === "fetch") { 41 event.respondWith(fetch(event.request)); 42 } else if (mode === "clone") { 43 // In order for the act of cloning to be interesting, we want the original 44 // request to remain alive so that any pipes end up having to buffer. 45 self.originalRequest = event.request; 46 event.respondWith(fetch(event.request.clone())); 47 } else { 48 event.respondWith( 49 new Response( 50 `<!DOCTYPE HTML><head><meta charset="utf-8"/></head><body> 51 <h1 id="error">Bad mode: ${mode}</h1> 52 <div id="source">ServiceWorker::Error</div> 53 <div id="blob">No, this is an error.</div> 54 </body>`, 55 { headers: { "Content-Type": "text/html" }, status: 400 } 56 ) 57 ); 58 } 59 });