-
Notifications
You must be signed in to change notification settings - Fork 0
/
shim.js
114 lines (103 loc) · 3.35 KB
/
shim.js
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
module.exports = (envSettings) => `
'use strict'
const URL = require('url').URL
const fetch = require('node-fetch')
const fab = require('./server')
const prodSettings = fab.getProdSettings ? fab.getProdSettings() : {}
const envSettings = ${JSON.stringify(envSettings)}
const settings = Object.assign({}, prodSettings, envSettings)
//Need to set this to work around a bug in a dependency of the webpack http(s) shim
global.location = { protocol: 'https:' }
global.fetch = fetch
global.Request = fetch.Request
global.Response = fetch.Response
global.Headers = fetch.Headers
global.URL = URL
const transformHeadersToFetch = (headers) => {
const fetch_headers = new Headers()
for (const header_name in headers) {
for (const header_info of headers[header_name]) {
fetch_headers.append(header_name, header_info.value)
}
}
return fetch_headers
}
const transformBodyToFetch = (body) => {
if (body) {
if (body.encoding === 'base64') {
return Buffer.from(body.data, body.encoding)
} else {
console.log('UNKNOWN ENCODING: ', body.encoding)
}
}
return null
}
const excludedHeaders = new Set([
'cache-control',
'content-encoding',
'content-length',
'connection',
'expect',
'keep-alive',
'proxy-authenticate',
'proxy-authorization',
'proxy-connection',
'trailer',
'transfer-encoding',
'upgrade',
'via',
'x-accel-buffering',
'x-accel-charset',
'x-accel-limit-rate',
'x-accel-redirect',
'x-cache',
'x-forwarded-proto',
'x-real-ip',
])
const excludedHeaderPrefixes = [/^x-amz-/i, /^x-amzn-/i, /^x-edge-/i]
const transformHeadersFromFetch = (headers) => {
const lambda_headers = {}
for (let [header, value] of headers.entries()) {
if (excludedHeaders.has(header.toLowerCase())) continue
if (excludedHeaderPrefixes.some((prefix) => prefix.exec(header))) continue
lambda_headers[header.toLowerCase()] = [{ header, value }]
}
return lambda_headers
}
const text_type = /^text/i
const transformResponseBody = async (response) => {
const content_type = response.headers.get('content-type')
if (content_type && text_type.exec(content_type)) {
const body = await response.text()
return { body, bodyEncoding: 'text' }
} else {
const bytes = await response.arrayBuffer()
const body = Buffer.from(bytes).toString('base64')
return { body, bodyEncoding: 'base64' }
}
}
exports.handler = async (event) => {
console.log(JSON.stringify(event, null, 2))
const cf_request = event.Records[0].cf.request
const host = cf_request.headers.host[0].value
const method = cf_request.method
const url = \`https://\${host}\${cf_request.uri}\`
const headers = transformHeadersToFetch(cf_request.headers)
const body = transformBodyToFetch(cf_request.body)
console.log({ url, method, headers, body })
const options =
body && method.toUpperCase() === 'GET' ? { method, headers } : { method, headers, body }
const fetch_request = new global.Request(url, options)
const fetch_response = await fab.render(fetch_request, settings)
const { body: res_body, bodyEncoding } = await transformResponseBody(fetch_response)
const lambda_response = {
status: '' + fetch_response.status,
statusDescription: fetch_request.statusText,
body: res_body,
bodyEncoding,
headers: transformHeadersFromFetch(fetch_response.headers),
}
console.log({ lambda_response })
return lambda_response
}
`