forked from techforum-repo/youttubedata
-
Notifications
You must be signed in to change notification settings - Fork 0
/
edgesiteincludehandler.txt
103 lines (90 loc) · 2.93 KB
/
edgesiteincludehandler.txt
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//Refer the original script - https://blog.cloudflare.com/edge-side-includes-with-cloudflare-workers/
//Modified the script - to include the main request headers while invoking the ESI resources
//- Support ESI source path with complete source URL, fetch the hostname and proptocol from original request
addEventListener("fetch", event => {
event.respondWith(fetchAndStream(event.request))
event.passThroughOnException()
})
async function fetchAndStream(request) {
let response = await fetch(request)
let contentType = response.headers.get('content-type')
if (!contentType || !contentType.startsWith("text/")) {
return response
}
let { readable, writable } = new TransformStream()
let newResponse = new Response(readable, response)
newResponse.headers.set('cache-control', 'max-age=0')
streamTransformBody(request,response.body, writable)
return newResponse
}
async function handleTemplate(request,encoder, templateKey) {
const linkRegex = /(esi:include.*src="(.*?)".*\/)/gm
let result = linkRegex.exec(templateKey);
let esi
if (!result) {
return encoder.encode(`<${templateKey}>`);
}
if (result[2]) {
esi = await subRequests(request,result[2]);
}
return encoder.encode(
`${esi}`
);
}
async function subRequests(request,target){
let requestHeaders = new Headers(request.headers);
let url = new URL(request.url)
let nocacheurl=url.protocol+'//'+url.hostname+target;
const init = {
method: 'GET',
headers:requestHeaders
}
let response = await fetch(nocacheurl, init)
let text = await response.text()
return text
}
async function streamTransformBody(request,readable, writable) {
const startTag = "<".charCodeAt(0);
const endTag = ">".charCodeAt(0);
let reader = readable.getReader();
let writer = writable.getWriter();
let templateChunks = null;
while (true) {
let { done, value } = await reader.read();
if (done) break;
while (value.byteLength > 0) {
if (templateChunks) {
let end = value.indexOf(endTag);
if (end === -1) {
templateChunks.push(value);
break;
} else {
templateChunks.push(value.subarray(0, end));
await writer.write(await translate(request,templateChunks));
templateChunks = null;
value = value.subarray(end + 1);
}
}
let start = value.indexOf(startTag);
if (start === -1) {
await writer.write(value);
break;
} else {
await writer.write(value.subarray(0, start));
value = value.subarray(start + 1);
templateChunks = [];
}
}
}
await writer.close();
}
async function translate(request,chunks) {
const decoder = new TextDecoder();
let templateKey = chunks.reduce(
(accumulator, chunk) =>
accumulator + decoder.decode(chunk, { stream: true }),
""
);
templateKey += decoder.decode();
return handleTemplate(request,new TextEncoder(), templateKey);
}