Skip to content

Commit

Permalink
introduce payloadAsStream option #154
Browse files Browse the repository at this point in the history
  • Loading branch information
adrai committed Jan 22, 2025
1 parent 013990b commit 6d711a7
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 3 deletions.
15 changes: 12 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = (app, options) => {
options.retainStage = options.retainStage !== undefined ? options.retainStage : false
options.pathParameterUsedAsPath = options.pathParameterUsedAsPath !== undefined ? options.pathParameterUsedAsPath : false
options.parseCommaSeparatedQueryParams = options.parseCommaSeparatedQueryParams !== undefined ? options.parseCommaSeparatedQueryParams : true
options.payloadAsStream = options.payloadAsStream !== undefined ? options.payloadAsStream : false
let currentAwsArguments = {}
if (options.decorateRequest) {
options.decorationPropertyName = options.decorationPropertyName || 'awsLambda'
Expand Down Expand Up @@ -110,7 +111,7 @@ module.exports = (app, options) => {
}

const prom = new Promise((resolve) => {
app.inject({ method, url, query, payload, headers, remoteAddress }, (err, res) => {
app.inject({ method, url, query, payload, headers, remoteAddress, payloadAsStream: options.payloadAsStream }, (err, res) => {
currentAwsArguments = {}
if (err) {
console.error(err)
Expand Down Expand Up @@ -149,14 +150,22 @@ module.exports = (app, options) => {

const ret = {
statusCode: res.statusCode,
body: isBase64Encoded ? res.rawPayload.toString('base64') : res.payload,
headers: res.headers,
isBase64Encoded
}

if (cookies && event.version === '2.0') ret.cookies = cookies
if (multiValueHeaders && (!event.version || event.version === '1.0')) ret.multiValueHeaders = multiValueHeaders
resolve(ret)

if (!options.payloadAsStream) {
ret.body = isBase64Encoded ? res.rawPayload.toString('base64') : res.payload
return resolve(ret)
}

resolve({
meta: ret,
stream: res.stream()
})
})
})
if (!callback) return prom
Expand Down
174 changes: 174 additions & 0 deletions test/stream.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
'use strict'

const { describe, it } = require('node:test')
const assert = require('node:assert')
const { promisify } = require('node:util')
const { Readable } = require('node:stream')
const fastify = require('fastify')
const awsLambdaFastify = require('../index')

const accumulate = promisify(function (stream, cb) {
const chunks = []
stream.on('error', cb)
stream.on('data', (chunk) => {
chunks.push(chunk)
})
stream.on('end', () => {
cb(null, Buffer.concat(chunks))
})
})

describe('Basic Stream Tests', () => {
it('GET a normal response as stream', async () => {
const app = fastify()

const evt = {
version: '2.0',
httpMethod: 'GET',
path: '/test',
headers: {
'X-My-Header': 'wuuusaaa'
},
cookies: ['foo=bar'],
queryStringParameters: ''
}

app.get('/test', async (request, reply) => {
assert.equal(
request.headers['x-my-header'],
'wuuusaaa',
'Header "X-My-Header" should match'
)

assert.equal(
request.headers.cookie,
'foo=bar',
'Cookie header should match'
)
assert.equal(
request.headers['user-agent'],
'lightMyRequest',
'User-agent header should match'
)
assert.equal(
request.headers.host,
'localhost:80',
'Host header should match'
)

reply.header('Set-Cookie', 'qwerty=one')
reply.header('Set-Cookie', 'qwerty=two')
reply.send({ hello: 'world' })
})

const proxy = awsLambdaFastify(app, { payloadAsStream: true })

const { meta, stream } = await proxy(evt)

assert.equal(meta.statusCode, 200, 'Status code should be 200')

const data = await accumulate(stream)
assert.equal(data.toString(), '{"hello":"world"}', 'Response body should match')

assert.equal(meta.isBase64Encoded, false, 'isBase64Encoded should be false')
assert.ok(meta.headers, 'Headers should be defined')
assert.equal(
meta.headers['content-type'],
'application/json; charset=utf-8',
'Content-Type should match'
)
assert.equal(
meta.headers['content-length'],
'17',
'Content-Length should match'
)
assert.ok(meta.headers.date, 'Date header should be defined')
assert.equal(
meta.headers.connection,
'keep-alive',
'Connection header should match'
)
assert.deepEqual(
meta.cookies,
['qwerty=one', 'qwerty=two'],
'Cookies should match'
)
})

it('GET a streamed response as stream', async () => {
const app = fastify()

const evt = {
version: '2.0',
httpMethod: 'GET',
path: '/test',
headers: {
'X-My-Header': 'wuuusaaa'
},
cookies: ['foo=bar'],
queryStringParameters: ''
}

app.get('/test', async (request, reply) => {
assert.equal(
request.headers['x-my-header'],
'wuuusaaa',
'Header "X-My-Header" should match'
)

assert.equal(
request.headers.cookie,
'foo=bar',
'Cookie header should match'
)
assert.equal(
request.headers['user-agent'],
'lightMyRequest',
'User-agent header should match'
)
assert.equal(
request.headers.host,
'localhost:80',
'Host header should match'
)

reply.header('Set-Cookie', 'qwerty=one')
reply.header('Set-Cookie', 'qwerty=two')
reply.header('content-type', 'application/json; charset=utf-8')
return reply.send(Readable.from(JSON.stringify({ hello: 'world' })))
})

const proxy = awsLambdaFastify(app, { payloadAsStream: true })

const { meta, stream } = await proxy(evt)

assert.equal(meta.statusCode, 200, 'Status code should be 200')

const data = await accumulate(stream)
assert.equal(data.toString(), '{"hello":"world"}', 'Response body should match')

assert.equal(meta.isBase64Encoded, false, 'isBase64Encoded should be false')
assert.ok(meta.headers, 'Headers should be defined')
assert.equal(
meta.headers['content-type'],
'application/json; charset=utf-8',
'Content-Type should match'
)
assert.equal(
meta.headers['content-length'],
undefined,
'Content-Length should not be present'
)
assert.ok(meta.headers.date, 'Date header should be defined')
assert.equal(
meta.headers.connection,
'keep-alive',
'Connection header should match'
)
assert.deepEqual(
meta.cookies,
['qwerty=one', 'qwerty=two'],
'Cookies should match'
)
})
})

0 comments on commit 6d711a7

Please sign in to comment.