forked from middyjs/middy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
109 lines (90 loc) · 2.54 KB
/
index.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
let https = require('https')
const { URL } = require('url')
const {
canPrefetch,
createPrefetchClient,
createClient
} = require('@middy/util')
const S3 = require('aws-sdk/clients/s3') // v2
// const { S3 } = require('@aws-sdk/client-s3') // v3
const defaults = {
AwsClient: S3, // Allow for XRay
awsClientOptions: {},
awsClientAssumeRole: undefined,
awsClientCapture: undefined,
httpsCapture: undefined,
disablePrefetch: false,
bodyType: undefined
}
const s3ObjectResponseMiddleware = (opts = {}) => {
const options = { ...defaults, ...opts }
if (!['stream', 'promise'].includes(options.bodyType)) {
throw new Error('bodyType is invalid.')
}
if (options.httpsCapture) {
https = options.httpsCapture(https)
}
let client
if (canPrefetch(options)) {
client = createPrefetchClient(options)
}
const s3ObjectResponseMiddlewareBefore = async (request) => {
const {
inputS3Url,
outputRoute,
outputToken
} = request.event.getObjectContext
request.internal.s3ObjectResponse = {
RequestRoute: outputRoute,
RequestToken: outputToken
}
const parsedInputS3Url = new URL(inputS3Url)
const fetchOptions = {
method: 'GET',
host: parsedInputS3Url.hostname,
path: parsedInputS3Url.pathname
}
request.context.s3Object = fetchType(options.bodyType, fetchOptions)
}
const s3ObjectResponseMiddlewareAfter = async (request) => {
if (!client) {
client = await createClient(options, request)
}
request.response.Body = request.response.Body ?? request.response.body
delete request.response.body
return client
.writeGetObjectResponse({
...request.response,
...request.internal.s3ObjectResponse
})
.promise()
.then(() => ({ statusCode: 200 })) // TODO test if needed
}
return {
before: s3ObjectResponseMiddlewareBefore,
after: s3ObjectResponseMiddlewareAfter
}
}
const fetchType = (type, fetchOptions) => {
if (type === 'stream') {
return fetchStream(fetchOptions)
} else if (type === 'promise') {
return fetchPromise(fetchOptions)
}
return null
}
const fetchStream = (fetchOptions) => {
return https.request(fetchOptions)
}
const fetchPromise = (fetchOptions) => {
return new Promise((resolve, reject) => {
let data = ''
const stream = fetchStream(fetchOptions)
stream.on('data', (chunk) => {
data += chunk
})
stream.on('end', () => resolve(data))
stream.on('error', (error) => reject(error))
})
}
module.exports = s3ObjectResponseMiddleware