UNPKG

2.12 kBPlain TextView Raw
1import http from 'http'
2import { parse as parseUrl } from 'url'
3import { parse as parseQuery } from 'query-string'
4import rawBody from 'raw-body'
5import mime from 'mime-types'
6import { AWS } from './types'
7
8// @see https://github.com/netlify/cli/blob/27bb7b9b30d465abe86f87f4274dd7a71b1b003b/src/utils/serve-functions.js#L167
9const BASE_64_MIME_REGEXP = /image|audio|video|application\/pdf|application\/zip|applicaton\/octet-stream/i
10function shouldBase64Encode(contentType: string) {
11 return Boolean(contentType) && BASE_64_MIME_REGEXP.test(contentType)
12}
13
14export async function requestToEvent(req: http.IncomingMessage): Promise<AWS['HandlerEvent']> {
15 // @see https://github.com/netlify/cli/blob/27bb7b9b30d465abe86f87f4274dd7a71b1b003b/src/utils/serve-functions.js#L208
16 const remoteAddress = String(req.headers['x-forwarded-for']) || req.connection.remoteAddress || ''
17 const ip = remoteAddress
18 .split(remoteAddress.includes('.') ? ':' : ',')
19 .pop()
20 ?.trim()
21 const isBase64Encoded = shouldBase64Encode(req.headers['content-type'] || '')
22 const body = req.headers['content-length']
23 ? await rawBody(req, {
24 limit: '1mb',
25 encoding: mime.charset(req.headers['content-type'] || '') || undefined,
26 })
27 : undefined
28
29 return {
30 path: req.url as string,
31 httpMethod: req.method as string,
32 // @ts-ignore TODO test set-cookie coming in as array
33 headers: {
34 ...req.headers,
35 'client-ip': ip,
36 },
37 // TODO should these headers be exclusively single value vs multi?
38 multiValueHeaders: Object.keys(req.headers).reduce((headers, key) => {
39 if (req.headers[key] && !(req.headers[key] as string).includes(',')) return headers // only include multi-value headers here
40
41 return {
42 ...headers,
43 // @ts-ignore TODO again, array headers
44 [key]: req.headers[key].split(','),
45 }
46 }, {}),
47 // @ts-ignore TODO do I need to keep these separate?
48 queryStringParameters: parseQuery(parseUrl(req.url).query),
49 body: body ? new Buffer(body).toString(isBase64Encoded ? 'base64' : 'utf8') : null,
50 isBase64Encoded,
51 }
52}