Last active
June 9, 2016 14:58
-
-
Save qgustavor/4a7222eb1867fe4c6751813176656630 to your computer and use it in GitHub Desktop.
Big File Download Test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <title>Big File Download Test</title> | |
| <p>Please wait: a Service Worker will be installed then the download will be started.</p> | |
| <p>You can also download a <a href="big-audio.wav">big random wav audio file</a> or listen it below:</p> | |
| <p><audio src="big-audio.wav" preload="none" controls></p> | |
| <p id="error-output"></p> | |
| <script> | |
| navigator.serviceWorker.register('sw.js', {scope: '.'}) | |
| .then(() => { | |
| location.href = './big-file.txt'; | |
| }, err => { | |
| document.getElementById('error-output') | |
| .appendChild(document.createTextNode('Error: ' + err.toString())); | |
| }); | |
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // From https://github.com/jakearchibald/isserviceworkerready/blob/master/src/demos/transform-stream/sw.js | |
| self.addEventListener('install', event => { | |
| self.skipWaiting(); | |
| }); | |
| self.addEventListener('activate', event => { | |
| clients.claim(); | |
| }); | |
| // From https://jakearchibald.com/2016/streams-ftw/ | |
| self.addEventListener('fetch', event => { | |
| var requestURL = new URL(event.request.url); | |
| if (requestURL.origin != location.origin) return; | |
| var textRequest = requestURL.pathname.endsWith('/big-file.txt'); | |
| var audioRequest = requestURL.pathname.endsWith('/big-audio.wav') | |
| var validRequest = textRequest || audioRequest; | |
| if (!validRequest) return; | |
| // Default: 1 GB file, 1 MB chunks: | |
| var fileSize = getParameterByName(requestURL.search, 'size') || Math.pow(1024, 3); | |
| var chunkSize = getParameterByName(requestURL.search, 'chunk') || Math.pow(1024, 2); | |
| var timeout; | |
| var cancelled; | |
| var header = audioRequest ? getAudioHeader(fileSize) : false; | |
| var stream = new ReadableStream({ | |
| start(controller) { | |
| // Our current position: | |
| var pos = 0; | |
| function push() { | |
| if (cancelled) return; | |
| // Are we done? | |
| if (pos >= fileSize) { | |
| controller.close(); | |
| return; | |
| } | |
| if (header) { | |
| controller.enqueue(header); | |
| pos += header.length; | |
| header = false; | |
| } | |
| // Push data: | |
| var randomData = generateRandomData(Math.min(chunkSize, fileSize - pos)); | |
| // Advance the position | |
| pos += randomData.length; | |
| controller.enqueue(randomData); | |
| // push again as fast as possible | |
| timeout = setTimeout(push, 0); | |
| } | |
| // Let's go! | |
| push(); | |
| }, | |
| cancel() { | |
| clearTimeout(timeout); | |
| cancelled = true; | |
| } | |
| }); | |
| event.respondWith(new Response(stream, { | |
| headers: { | |
| 'Content-Type': 'text/plain', | |
| 'Content-Disposition': 'attachment; filename="big-file.' + ( audioRequest? 'wav' : 'txt' ) + '"', | |
| 'Content-Length': fileSize | |
| } | |
| })); | |
| }); | |
| function generateRandomData(l) { | |
| var data = new Uint8Array(l); | |
| do { | |
| data[--l] = Math.random() * 256 | 0; | |
| } while (l); | |
| return data; | |
| } | |
| function getParameterByName(query, name) { | |
| var match = RegExp('[?&]' + name + '=([^&]*)', 'g').exec(query); | |
| return match && decodeURIComponent(match[1].replace(/\+/g, ' ')); | |
| } | |
| function pack(b,a){return[new Uint8Array([a,a>>8]),new Uint8Array([a,a>>8,a>>16,a>>24])][b]} | |
| function getAudioHeader(size) { | |
| return concatenate(Uint8Array, ["RIFF",pack(1,52),"WAVE","fmt ",pack(1,16),pack(0,1),pack(0,1),pack(1,44100), | |
| pack(1,88200),pack(0,2),pack(0,16),"data",pack(1,16*size/8)]); | |
| } | |
| function concatenate(resultConstructor, arrays) { | |
| let totalLength = 0; | |
| for (let arr of arrays) { | |
| totalLength += arr.length; | |
| } | |
| let result = new resultConstructor(totalLength); | |
| let offset = 0; | |
| for (let arr of arrays) { | |
| if (typeof arr === 'string') { | |
| arr = new Uint8Array(arr.split('').map(e => e.charCodeAt(0))); | |
| } | |
| result.set(arr, offset); | |
| offset += arr.length; | |
| } | |
| return result; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment