forked from vantage-sh/ec2instances.info
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathworker.js
More file actions
129 lines (118 loc) · 3.87 KB
/
Copy pathworker.js
File metadata and controls
129 lines (118 loc) · 3.87 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
async function getAsset(path, env, ctx, cacheKey, isHead) {
// Attempt to decode the path.
try {
path = decodeURIComponent(path);
} catch {
return new Response(isHead ? null : "Invalid path", {
status: 400,
});
}
const value = await env.ASSETS_KV.getWithMetadata(path, {
type: "stream",
});
if (!value.value) {
// Check the bucket
const bucket = await env.ASSETS_BUCKET.get(path);
if (!bucket) {
// Handle a 404
const notFoundAsset = await env.ASSETS_KV.get("404", {
type: "arrayBuffer",
});
if (!notFoundAsset) {
return new Response(isHead ? null : "Internal server error", {
status: 500,
});
}
return new Response(isHead ? null : notFoundAsset, {
status: 404,
headers: {
"Content-Type": "text/html; charset=utf-8",
},
});
}
// Write the asset to the cache and return it
const headers = new Headers();
bucket.writeHttpMetadata(headers);
headers.set("etag", bucket.httpEtag);
if (!path.endsWith(".xml")) {
// Ignore .xml files because they are for search engines
headers.append("Cache-Control", "s-maxage=86400");
}
const resp = new Response(isHead ? null : bucket.body, {
headers,
});
ctx.waitUntil(caches.default.put(cacheKey, resp.clone()));
return resp;
}
// Return the asset from the cache.
const xmlLine = path.endsWith(".xml")
? {}
: { "Cache-Control": "s-maxage=86400" };
const resp = new Response(value.value, {
status: path === "404" ? 404 : 200,
headers: {
...value.metadata,
...xmlLine,
},
});
ctx.waitUntil(caches.default.put(cacheKey, resp.clone()));
return resp;
}
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// Handle old hostname redirects.
if (
url.hostname === "ec2instances.info" ||
url.hostname === "www.ec2instances.info"
) {
url.hostname = "instances.vantage.sh";
return Response.redirect(url, 301);
}
// Handle HTTP redirects.
if (url.protocol === "http:") {
url.protocol = "https:";
return Response.redirect(url, 301);
}
// Construct the cache key from the cache URL
const cacheUrl = new URL(url);
cacheUrl.searchParams.delete("id");
const cacheKey = new Request(cacheUrl.toString(), request);
const cache = caches.default;
const cacheResponse = await cache.match(cacheKey);
if (cacheResponse) {
// Bail early if we have a cache hit
return cacheResponse;
}
// Get the path.
let path = url.pathname.substring(1);
if (path === "index.html") {
// Redirect to root
url.pathname = "/";
return Response.redirect(url, 301);
}
if (path === "") path = "index.html";
if (path.endsWith("/")) {
// Redirect to no trailing slash
url.pathname = "/" + path.slice(0, -1);
return Response.redirect(url, 301);
}
// Handle non-GET requests.
if (request.method !== "GET" && request.method !== "HEAD") {
return new Response("Method not allowed", {
status: 405,
headers: {
Allow: "GET, HEAD",
},
});
}
// Try to get the asset.
return await getAsset(
path,
env,
ctx,
cacheKey,
request.method === "HEAD",
);
},
};