-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloudfront.ts
114 lines (100 loc) · 3.04 KB
/
cloudfront.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
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
import {
CloudFrontRequestEvent,
CloudFrontRequestResult,
CloudFrontRequest,
CloudFrontHeaders,
Context,
} from 'aws-lambda'
import { envKey, sessionIdHeaderName } from './config'
import { parseQueryString } from './parse-querystring'
import { EventInput, HTTPMethod, RCHeaders, RCRequest, RCResponse } from './types'
import { getEnvRegion } from './utils'
import { parseCookies } from './parse-cookies'
export type RequestEvent = CloudFrontRequestEvent
export type ResponseEvent = CloudFrontRequestResult
const requestBodyHandler = (body: CloudFrontRequest['body']) => {
if (body) {
if (body.encoding === 'base64') {
return Buffer.from(body.data, 'base64').toString('utf8')
}
return body.data
}
}
const requestHeadersHandler = (headers: CloudFrontHeaders): RCHeaders => {
const heads: RCHeaders = {}
Object.entries(headers).forEach(([k, v]) => {
if (k !== envKey) {
heads[k] = v.map(({ value }) => value)
}
})
return heads
}
const responseHeadersHandler = (headers: RCHeaders): CloudFrontHeaders => {
const heads: CloudFrontHeaders = {}
Object.entries(headers).forEach(([k, v]) => {
if (Array.isArray(v)) {
heads[k] = v.map((value) => ({ key: k, value }))
} else {
heads[k] = [{ key: k, value: v }]
}
})
return heads
}
const getEnv = (req: CloudFrontRequest): Record<string, any> => {
const header = req.origin?.s3?.customHeaders[envKey]
const str = header ? header[0].value : undefined
return str ? JSON.parse(str) : {}
}
export const toRCRequest = <EnvType>(event: RequestEvent, context: Context): RCRequest<EnvType> => {
const request = event.Records[0].cf.request
const body = requestBodyHandler(request.body)
const query = parseQueryString(request.querystring)
const { region } = getEnvRegion()
const headers = requestHeadersHandler(request.headers)
const host = Array.isArray(headers['host']) ? headers['host'][0] : headers['host']
let env = getEnv(request)
if (env.domainMapping) {
env = env.domainMapping[host]
}
const { functionName, functionVersion, awsRequestId } = context
const obj: RCRequest<EnvType> = {
method: request.method as HTTPMethod,
path: request.uri,
headers,
host,
env: env as EnvType,
region,
cookies: headers.cookie ? parseCookies(headers.cookie) : [],
meta: {
event,
sessionId: headers[sessionIdHeaderName]?.toString(),
functionName,
functionVersion,
invocationId: awsRequestId,
},
}
if (query && Object.keys(query).length) {
obj['query'] = query
}
if (body) {
obj['body'] = body
}
return obj
}
export const isRequestEvent = (event: EventInput): event is RequestEvent => {
if ((event as CloudFrontRequestEvent).hasOwnProperty('Records')) {
return true
}
return false
}
export const handleRCResponse = (res: RCResponse): ResponseEvent => {
const obj: ResponseEvent = {
headers: responseHeadersHandler(res.headers),
status: res.status.toString(),
}
if (res.body) {
obj['body'] = res.body
obj['bodyEncoding'] = 'text'
}
return obj
}