forked from jimmywarting/StreamSaver.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mitm.html
79 lines (69 loc) · 2.76 KB
/
mitm.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<!--
mitm.html is the lite "man in the middle"
This is only meant to signal the opener's messageChannel to
the service worker - when that is done this mitm can be closed
but it's better to keep it alive since this also stops the sw
from restarting
The service worker is capable of intercepting all request and fork their
own "fake" response - wish we are going to craft
when the worker then receives a stream then the worker will tell the opener
to open up a link that will start the download
-->
<script>
let host = 'jimmywarting.github.io'
// Service worker only works on https, 127.0.0.1 and localhost
// So we just redirect asap
if (window.location.host === host && window.location.protocol !== 'https:') { window.location.protocol = 'https:' }
// This will prevent the sw from restarting
let keepAlive = sw => {
keepAlive = () => {}
setInterval(() => {
sw.postMessage('ping', [new MessageChannel().port2])
}, 29E3) // 29sec
}
// message event is the first thing we need to setup a listner for
// don't want the opener to do a random timeout - instead they can listen for
// the ready event
window.onmessage = event => {
let { data, ports } = event
// It's important to have a messageChannel, don't want to interfere
// with other simultaneous downloads
if (!ports || !ports.length) { throw new TypeError("Mehhh! You didn't send a messageChannel") }
// Register the worker, then forward the dataChannel to the worker
// So they can talk directly, so we don't have to be "the middle man" any
// longer
navigator.serviceWorker.getRegistration('./').then(swReg => {
return swReg || navigator.serviceWorker.register('sw.js', { scope: './' })
}).then(swReg => {
// This sends the message data as well as transferring
// messageChannel.port2 to the service worker. The service worker can
// then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
const swRegTmp = swReg.installing || swReg.waiting
if (swReg.active) {
keepAlive(swReg.active)
return swReg.active.postMessage(
data,
data.readableStream
? [ ports[0], data.readableStream ]
: [ ports[0] ]
)
}
swRegTmp.onstatechange = () => {
if (swRegTmp.state === 'activated') {
swRegTmp.onstatechange = null
swReg.active.postMessage(
data,
data.readableStream
? [ ports[0], data.readableStream ]
: [ ports[0] ]
)
keepAlive(swReg.active)
}
}
})
}
// The opener can't listen to onload event, so we need to help em out!
// (telling them that we are ready to accept postMessage's)
window.opener && window.opener.postMessage('StreamSaver::loadedPopup', '*')
</script>