Skip to content

Commit da388c5

Browse files
committed
feat(ops): CF edge-cache /data + maintenance Worker + 4xx no-cache
Cloudflare ops hardening (zone cohenjikan.com), configured via API from local: - Cache Rule: edge-cache /data/ shards (respect origin TTL) — fixes slow big-poet loads (陆游 2.6MB slice etc. now HIT from edge instead of re-fetching from the single Oracle origin every time). Verified poems Range 206 bytes stay correct through cache (RAW contract intact). - Cache Rule: never edge-cache 4xx on shiyun — prevents the 404-cache outage that earlier needed a ?query workaround. - maintenance Worker (deploy/maintenance-worker.js, route shiyun.cohenjikan.com/*): origin 5xx/unreachable serves an inlined 诗云-style 维护中 page (deploy/maintenance.html, with contact email) instead of CF's 5xx page. ?__maint_preview=1 previews it; normal traffic passes through transparently.
1 parent 4b91697 commit da388c5

2 files changed

Lines changed: 176 additions & 0 deletions

File tree

deploy/maintenance-worker.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// 诗云维护页 Worker — 绑定 route「shiyun.cohenjikan.com/」(只拦页面导航,/data 与 /assets 直连
2+
// 边缘缓存,不进 Worker → 省调用额度)。源站正常时透明放行;源站 5xx / 不可达(整机宕机)时返回内联
3+
// 维护页(HTML 嵌在本脚本里,不依赖源站,所以源站全挂也能显示)。?__maint_preview=1 可强制预览。
4+
addEventListener("fetch", (event) => event.respondWith(handle(event.request)));
5+
6+
async function handle(request) {
7+
const url = new URL(request.url);
8+
if (url.searchParams.has("__maint_preview")) return maintenance();
9+
try {
10+
const resp = await fetch(request);
11+
if (resp.status >= 500 && resp.status <= 599) return maintenance();
12+
return resp;
13+
} catch (_e) {
14+
return maintenance();
15+
}
16+
}
17+
18+
function maintenance() {
19+
return new Response(MAINTENANCE_HTML, {
20+
status: 503,
21+
headers: {
22+
"content-type": "text/html; charset=utf-8",
23+
"retry-after": "120",
24+
"cache-control": "no-store",
25+
},
26+
});
27+
}
28+
29+
const MAINTENANCE_HTML = `<!doctype html>
30+
<html lang="zh-CN">
31+
<head>
32+
<meta charset="utf-8" />
33+
<meta name="viewport" content="width=device-width, initial-scale=1" />
34+
<title>诗云 · 维护中 / Poetry Cloud · Under Maintenance</title>
35+
<meta http-equiv="refresh" content="30" />
36+
<style>
37+
* { margin: 0; padding: 0; box-sizing: border-box; }
38+
html, body { height: 100%; }
39+
body {
40+
background: radial-gradient(ellipse 120% 80% at 50% 28%, #0c1426 0%, #060a14 55%, #020306 100%);
41+
color: #e9e1cb;
42+
font-family: "Noto Serif CJK SC", "Source Han Serif SC", "Songti SC", STSong, ui-serif, Georgia, serif;
43+
min-height: 100vh; display: flex; align-items: center; justify-content: center;
44+
overflow: hidden; position: relative; -webkit-font-smoothing: antialiased;
45+
}
46+
.stars { position: absolute; inset: 0; pointer-events: none; }
47+
.stars i {
48+
position: absolute; inset: -50%; background-repeat: repeat;
49+
animation: drift 200s linear infinite, twinkle 6s ease-in-out infinite alternate;
50+
}
51+
.stars i:nth-child(1){ background-image:
52+
radial-gradient(1.5px 1.5px at 20% 30%, #fff8 40%, transparent),
53+
radial-gradient(1px 1px at 70% 60%, #cfe3ff7a 40%, transparent),
54+
radial-gradient(1.5px 1.5px at 45% 80%, #ffe9b86b 40%, transparent),
55+
radial-gradient(1px 1px at 85% 15%, #fff6 40%, transparent);
56+
background-size: 340px 340px; }
57+
.stars i:nth-child(2){ background-image:
58+
radial-gradient(1px 1px at 30% 50%, #9fc0ff66 40%, transparent),
59+
radial-gradient(1.5px 1.5px at 60% 20%, #fff5 40%, transparent),
60+
radial-gradient(1px 1px at 90% 70%, #ffd98a55 40%, transparent);
61+
background-size: 520px 520px; animation-duration: 320s, 9s; opacity:.7; }
62+
@keyframes drift { to { transform: translate(-12%, -8%); } }
63+
@keyframes twinkle { from { opacity:.5; } to { opacity:1; } }
64+
.card { position: relative; z-index: 1; text-align: center; padding: 3rem 1.8rem; max-width: 540px; }
65+
.brand { font-size: clamp(2.4rem, 8vw, 3.4rem); letter-spacing: .34em; font-weight: 600;
66+
color: #ecca7c; text-indent: .34em; text-shadow: 0 0 24px #e9b85033, 0 0 60px #e9b85018;
67+
animation: glow 5s ease-in-out infinite alternate; }
68+
@keyframes glow { from { text-shadow: 0 0 18px #e9b85022, 0 0 44px #e9b85010; }
69+
to { text-shadow: 0 0 30px #e9b85044, 0 0 78px #e9b85022; } }
70+
.latin { margin-top: .5rem; font-size: .82rem; letter-spacing: .42em; text-indent:.42em;
71+
color: #8a93a6; text-transform: uppercase; }
72+
.status { margin-top: 2.4rem; font-size: clamp(1.15rem, 4.5vw, 1.5rem); font-weight: 600; color: #f1ead6; }
73+
.msg { margin-top: 1.1rem; line-height: 2; font-size: clamp(.92rem, 3.4vw, 1.02rem); color: #b9b8a8; }
74+
.dots { display:inline-block; width:1.4em; text-align:left; }
75+
.dots::after { content:""; animation: dots 1.6s steps(4,end) infinite; }
76+
@keyframes dots { 0%{content:"";} 25%{content:"·";} 50%{content:"··";} 75%{content:"···";} 100%{content:"";} }
77+
.rule { width: 64px; height: 1px; margin: 2.2rem auto 0;
78+
background: linear-gradient(90deg, transparent, #e9b85055, transparent); }
79+
.mail { margin-top: 1.6rem; font-size: .9rem; color: #8a93a6; }
80+
.mail a { color: #ecca7c; text-decoration: none; border-bottom: 1px solid #ecca7c40; padding-bottom: 1px; }
81+
.mail a:hover { border-bottom-color: #ecca7c; }
82+
</style>
83+
</head>
84+
<body>
85+
<div class="stars" aria-hidden="true"><i></i><i></i></div>
86+
<main class="card">
87+
<div class="brand">诗云</div>
88+
<div class="latin">Poetry Cloud</div>
89+
<h1 class="status">星图正在维护中<span class="dots"></span></h1>
90+
<p class="msg">
91+
一切可能的诗,仍静静悬在虚空里等待。<br />
92+
我们正在校准星图,请稍候片刻——<br />
93+
页面将自动恢复,无需刷新。
94+
</p>
95+
<div class="rule" aria-hidden="true"></div>
96+
<p class="mail">紧急事宜请联系 · <a href="mailto:q63725959@gmail.com">q63725959@gmail.com</a></p>
97+
</main>
98+
</body>
99+
</html>`;

deploy/maintenance.html

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<!doctype html>
2+
<html lang="zh-CN">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<title>诗云 · 维护中 / Poetry Cloud · Under Maintenance</title>
7+
<!-- 源站恢复后自动回到正常站(CF Worker 探测到源站 OK 即返回真页面) -->
8+
<meta http-equiv="refresh" content="30" />
9+
<style>
10+
/* 完全自包含:源站不可用时连外部 CSS/字体/图片都加载不了,所以全内联 + 系统字体 + CSS 画星点 */
11+
* { margin: 0; padding: 0; box-sizing: border-box; }
12+
html, body { height: 100%; }
13+
body {
14+
background: radial-gradient(ellipse 120% 80% at 50% 28%, #0c1426 0%, #060a14 55%, #020306 100%);
15+
color: #e9e1cb;
16+
font-family: "Noto Serif CJK SC", "Source Han Serif SC", "Songti SC", STSong, ui-serif, Georgia, serif;
17+
min-height: 100vh; display: flex; align-items: center; justify-content: center;
18+
overflow: hidden; position: relative; -webkit-font-smoothing: antialiased;
19+
}
20+
/* 星点:三层 radial-gradient 平铺,缓慢明灭 */
21+
.stars { position: absolute; inset: 0; pointer-events: none; }
22+
.stars i {
23+
position: absolute; inset: -50%;
24+
background-repeat: repeat;
25+
animation: drift 200s linear infinite, twinkle 6s ease-in-out infinite alternate;
26+
}
27+
.stars i:nth-child(1){ background-image:
28+
radial-gradient(1.5px 1.5px at 20% 30%, #fff8 40%, transparent),
29+
radial-gradient(1px 1px at 70% 60%, #cfe3ff7a 40%, transparent),
30+
radial-gradient(1.5px 1.5px at 45% 80%, #ffe9b86b 40%, transparent),
31+
radial-gradient(1px 1px at 85% 15%, #fff6 40%, transparent);
32+
background-size: 340px 340px; }
33+
.stars i:nth-child(2){ background-image:
34+
radial-gradient(1px 1px at 30% 50%, #9fc0ff66 40%, transparent),
35+
radial-gradient(1.5px 1.5px at 60% 20%, #fff5 40%, transparent),
36+
radial-gradient(1px 1px at 90% 70%, #ffd98a55 40%, transparent);
37+
background-size: 520px 520px; animation-duration: 320s, 9s; opacity:.7; }
38+
@keyframes drift { to { transform: translate(-12%, -8%); } }
39+
@keyframes twinkle { from { opacity:.5; } to { opacity:1; } }
40+
41+
.card { position: relative; z-index: 1; text-align: center; padding: 3rem 1.8rem; max-width: 540px; }
42+
.brand { font-size: clamp(2.4rem, 8vw, 3.4rem); letter-spacing: .34em; font-weight: 600;
43+
color: #ecca7c; text-indent: .34em;
44+
text-shadow: 0 0 24px #e9b85033, 0 0 60px #e9b85018;
45+
animation: glow 5s ease-in-out infinite alternate; }
46+
@keyframes glow { from { text-shadow: 0 0 18px #e9b85022, 0 0 44px #e9b85010; }
47+
to { text-shadow: 0 0 30px #e9b85044, 0 0 78px #e9b85022; } }
48+
.latin { margin-top: .5rem; font-size: .82rem; letter-spacing: .42em; text-indent:.42em;
49+
color: #8a93a6; text-transform: uppercase; }
50+
.status { margin-top: 2.4rem; font-size: clamp(1.15rem, 4.5vw, 1.5rem); font-weight: 600; color: #f1ead6; }
51+
.msg { margin-top: 1.1rem; line-height: 2; font-size: clamp(.92rem, 3.4vw, 1.02rem); color: #b9b8a8; }
52+
.dots { display:inline-block; width:1.4em; text-align:left; }
53+
.dots::after { content:""; animation: dots 1.6s steps(4,end) infinite; }
54+
@keyframes dots { 0%{content:"";} 25%{content:"·";} 50%{content:"··";} 75%{content:"···";} 100%{content:"";} }
55+
.rule { width: 64px; height: 1px; margin: 2.2rem auto 0;
56+
background: linear-gradient(90deg, transparent, #e9b85055, transparent); }
57+
.mail { margin-top: 1.6rem; font-size: .9rem; color: #8a93a6; }
58+
.mail a { color: #ecca7c; text-decoration: none; border-bottom: 1px solid #ecca7c40; padding-bottom: 1px; }
59+
.mail a:hover { border-bottom-color: #ecca7c; }
60+
</style>
61+
</head>
62+
<body>
63+
<div class="stars" aria-hidden="true"><i></i><i></i></div>
64+
<main class="card">
65+
<div class="brand">诗云</div>
66+
<div class="latin">Poetry Cloud</div>
67+
<h1 class="status">星图正在维护中<span class="dots"></span></h1>
68+
<p class="msg">
69+
一切可能的诗,仍静静悬在虚空里等待。<br />
70+
我们正在校准星图,请稍候片刻——<br />
71+
页面将自动恢复,无需刷新。
72+
</p>
73+
<div class="rule" aria-hidden="true"></div>
74+
<p class="mail">紧急事宜请联系 · <a href="mailto:q63725959@gmail.com">q63725959@gmail.com</a></p>
75+
</main>
76+
</body>
77+
</html>

0 commit comments

Comments
 (0)