/
context.ts
76 lines (72 loc) · 2.27 KB
/
context.ts
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
import util from "../shared/util.ts";
import { SessionImpl } from "./session.ts";
import type { ConnInfo, Context, HTMLRewriterHandlers, Session, SessionOptions } from "./types.ts";
type ContextOptions = {
connInfo?: ConnInfo;
session?: SessionOptions;
};
/** create a context object */
export function createContext(
req: Request,
next: () => Promise<Response> | Response,
options?: ContextOptions,
): Context {
let cookies: Map<string, string> | null = null;
let session: Session<Record<string, unknown>> | null = null;
const ctx: Context = {
connInfo: options?.connInfo,
params: {},
headers: new Headers(),
cookies: {
get(name: string) {
if (cookies === null) {
cookies = new Map<string, string>();
const cookieHeader = req.headers.get("Cookie");
if (cookieHeader) {
for (const cookie of cookieHeader.split(";")) {
const [key, value] = util.splitBy(cookie, "=");
cookies.set(key.trim(), value);
}
}
}
return cookies.get(name);
},
},
// deno-lint-ignore ban-ts-comment
// @ts-ignore
async getSession(): Promise<Session<Record<string, unknown>>> {
if (session !== null) {
return session;
}
const cookieName = options?.session?.cookie?.name ?? "session";
let sid = ctx.cookies.get(cookieName);
if (sid && options?.session?.secret) {
const [rid, signature] = util.splitBy(sid, ".");
if (!signature || signature !== await util.hmacSign(rid, options?.session?.secret, "SHA-256")) {
sid = undefined;
}
}
if (!sid) {
sid = await util.computeHash("SHA-1", crypto.randomUUID());
if (options?.session?.secret) {
sid = sid + "." + util.hmacSign(sid, options.session.secret);
}
}
const sessionImpl = new SessionImpl<Record<string, unknown>>(
sid,
options?.session,
);
await sessionImpl.read();
session = sessionImpl;
return session;
},
__htmlRewriterHandlers: [],
htmlRewriter: {
on: (selector: string, handlers: HTMLRewriterHandlers) => {
(ctx.__htmlRewriterHandlers as unknown[]).push([selector, handlers]);
},
},
next,
};
return ctx;
}