aboutsummaryrefslogtreecommitdiff
path: root/src/app.ts
diff options
context:
space:
mode:
authorJoe Mou <dev@mou.fo>2026-08-27 14:08:06 -0400
committerJoe Mou <dev@mou.fo>2026-08-27 14:53:38 -0400
commit4797a627f461204b289f95f61b64e3dab8bc00ff (patch)
treea044ef3d0419c95aad9fa98a093e0c39bdce5459 /src/app.ts
parent7c928d30b16b37624841c4615c0d4bda426e4159 (diff)
Display PDF blobs
GitHub renders a PDF with a viewer of its own and so ships no content for one, leaving the blob view with nothing to show. Its raw bytes come as application/octet-stream, which browsers download rather than display, so serve them from a new embed route that retypes them and point an <object> at that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BErPR92xppzGFXkPqXPYj2
Diffstat (limited to 'src/app.ts')
-rw-r--r--src/app.ts26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/app.ts b/src/app.ts
index 9781a98..33b408e 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -10,6 +10,7 @@ import {
getGitHubLatestCommit,
getGitHubOwner,
getGitHubPulls,
+ getGitHubRaw,
getGitHubRefs,
getGitHubRelease,
getGitHubReleases,
@@ -120,6 +121,31 @@ export function createApp(eta: Eta) {
);
});
+ // This is not a native GitHub route, but instead it lets us render blob
+ // content whose raw headers prevent hotlinking.
+ app.get("/:owner/:repo/embed/:type/:branch/:path{.*}", async (c) => {
+ const { owner, repo, type, branch, path } = c.req.param();
+
+ if (type !== "pdf") {
+ return c.notFound();
+ }
+
+ let response: Response;
+ try {
+ response = await getGitHubRaw(owner, repo, branch, path);
+ } catch (e) {
+ c.status(e instanceof GitHubHTTPError ? (e.status as StatusCode) : 500);
+ return c.body(null);
+ }
+
+ let contentType = response.headers.get("Content-Type");
+ if (contentType === null || contentType === "application/octet-stream") {
+ contentType = "application/pdf";
+ }
+
+ return new Response(response.body, { headers: { "Content-Type": contentType } });
+ });
+
app.get("/:owner/:repo/issues", async (c) => {
const { owner, repo } = c.req.param();
const q = c.req.query("q");