Skip to content

Commit

Permalink
fix: add query strings to lambda@edge
Browse files Browse the repository at this point in the history
  • Loading branch information
brett-vendia committed Feb 4, 2021
1 parent a9b414e commit b15a72c
Show file tree
Hide file tree
Showing 12 changed files with 13,472 additions and 41 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ coverage
sam-template.packaged.yaml
vendia-serverless-express-*.tgz
dist/
examples/nextjs
examples/nextjs
examples/nestjs
22 changes: 9 additions & 13 deletions __tests__/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const bodyParser = require('body-parser')
const ejs = require('ejs').__express
const serverlessExpress = require('../src/index')
const {
log,
makeEvent,
makeResponse,
EACH_MATRIX
Expand All @@ -20,7 +19,7 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo
app = express()
router = express.Router()
app.use('/', router)
serverlessExpressInstance = serverlessExpress({ app, log })
serverlessExpressInstance = serverlessExpress({ app })
})

test('handler returns promise', () => {
Expand Down Expand Up @@ -66,7 +65,6 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo
})

test('GET JSON', async () => {
// TODO: Fix lambdaEdge query strings
const multiValueQueryStringParameters = {
singleNormal: ['1'],
singleSpecial: ['hello world!'],
Expand All @@ -92,16 +90,14 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo
const response = await serverlessExpressInstance.handler(event)
const expectedResponse = makeResponse({
eventSourceName,
body: eventSourceName === 'lambdaEdge'
? '{}'
: JSON.stringify({
...queryStringParameters,
arr: multiValueQueryStringParameters.arr
}),
body: JSON.stringify({
...queryStringParameters,
arr: multiValueQueryStringParameters.arr
}),
multiValueHeaders: {
'content-length': ['82'],
etag: eventSourceName === 'lambdaEdge' ? ['W/"2-vyGp6PvFo4RvsFtPoIWeCReyIC8"'] : ['W/"52-QR4hWttXm/4xeZPYy7nze/EjYXg"'],
'x-custom-header': eventSourceName === 'lambdaEdge' ? ['undefined'] : ['1']
etag: ['W/"52-QR4hWttXm/4xeZPYy7nze/EjYXg"'],
'x-custom-header': ['1']
}
})
expect(response).toEqual(expectedResponse)
Expand Down Expand Up @@ -130,7 +126,7 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo
path: '/users',
httpMethod: 'GET'
})
const serverlessExpressInstanceWithCallbackResolutionMode = serverlessExpress({ app, log, resolutionMode: 'CALLBACK' })
const serverlessExpressInstanceWithCallbackResolutionMode = serverlessExpress({ app, resolutionMode: 'CALLBACK' })
serverlessExpressInstanceWithCallbackResolutionMode.handler(event, {}, callback)
})

Expand All @@ -157,7 +153,7 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo
path: '/users',
httpMethod: 'GET'
})
const serverlessExpressInstanceWithContextResolutionMode = serverlessExpress({ app, log, resolutionMode: 'CONTEXT' })
const serverlessExpressInstanceWithContextResolutionMode = serverlessExpress({ app, resolutionMode: 'CONTEXT' })
serverlessExpressInstanceWithContextResolutionMode.handler(event, context)
})

Expand Down
13,427 changes: 13,424 additions & 3 deletions examples/lambda-edge/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/lambda-edge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@vendia/serverless-express": "^4.0.0",
"@vendia/serverless-express": "^4.1.1",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"cors": "^2.8.5",
Expand Down
15 changes: 1 addition & 14 deletions examples/lambda-edge/src/lambda.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
const serverlessExpress = require('@vendia/serverless-express')
const app = require('./app')

// NOTE: If you get ERR_CONTENT_DECODING_FAILED in your browser, this is likely
// due to a compressed response (e.g. gzip) which has not been handled correctly
// by serverless-express and/or API Gateway. Add the necessary MIME types to
// binaryMimeTypes below, then redeploy (`npm run package-deploy`)
const binaryMimeTypes = [
// '*/*'
]

const se = serverlessExpress({
app,
binaryMimeTypes
})

exports.handler = se.handler
exports.handler = serverlessExpress({ app }).handler
Binary file not shown.
14 changes: 13 additions & 1 deletion jest-helpers/lambda-edge-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ function makeLambdaEdgeEvent (values = {}) {
const mergedEvent = mergeDeep(baseEvent, values)

if (!mergedEvent.request.uri) mergedEvent.request.uri = values.path

if (!mergedEvent.request.querystring && values.multiValueQueryStringParameters) {
const multiValueQueryStringParametersToArray = []
Object.entries(values.multiValueQueryStringParameters)
.forEach(([qKey, qValues]) => {
qValues.forEach(qValue => {
multiValueQueryStringParametersToArray.push([qKey, qValue])
})
})
const querystring = new URLSearchParams(multiValueQueryStringParametersToArray)
mergedEvent.request.querystring = querystring.toString()
}

if (!mergedEvent.request.method) mergedEvent.request.method = values.httpMethod

if (!mergedEvent.request.body.data) {
Expand Down Expand Up @@ -165,7 +178,6 @@ function makeLambdaEdgeResponse (values = {}) {
values.bodyEncoding = values.isBase64Encoded ? 'base64' : 'text'
delete values.isBase64Encoded
const mergedResponse = mergeDeep(baseResponse, values)

if (values.body) {
mergedResponse.body.data = values.body
}
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
"jest": {
"collectCoverageFrom": [
"src/**"
],
"testPathIgnorePatterns": [
"examples/nestjs"
]
},
"devDependencies": {
Expand Down
14 changes: 10 additions & 4 deletions src/event-sources/aws/lambda-edge.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
const url = require('url')
const { getEventBody } = require('../utils')

// Lambda@Edge fails if certain headers are returned
const RESPONSE_HEADERS_DENY_LIST = ['content-length']

function getRequestValuesFromLambdaEdgeEvent ({ event }) {
const cloudFormationRequest = event.Records[0].cf.request
const cloudFrontRequest = event.Records[0].cf.request
const {
headers: headersMap,
uri: path,
uri,
method,
querystring,
body: requestBodyObject = {},
clientIp
} = cloudFormationRequest
} = cloudFrontRequest
let body = null

const headers = {}
Expand All @@ -29,7 +31,11 @@ function getRequestValuesFromLambdaEdgeEvent ({ event }) {
headers['content-length'] = Buffer.byteLength(body, isBase64Encoded ? 'base64' : 'utf8')
}

// TODO: include querystring params in path
const path = url.format({
pathname: uri,
search: querystring
})

const { host } = headers
return {
method,
Expand Down
5 changes: 4 additions & 1 deletion src/logger.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const {
LOG_LEVEL = process.env.NODE_ENV === 'development' ? 'debug' : 'error'
} = process.env
const logger = {
// TODO: allow users to set log level without having to provide the other log methods
level: process.env.NODE_ENV === 'development' ? 'debug' : 'error',
level: LOG_LEVEL,
error (message, additional) {
if (!logger.level.includes('debug', 'verbose', 'info', 'warn', 'error')) return
console.error({
Expand Down
5 changes: 3 additions & 2 deletions src/proxy.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const util = require('util')
const { setCurrentInvoke } = require('./current-invoke')
const { getEventSource } = require('./event-sources')
const { getEventSourceNameBasedOnEvent } = require('./event-sources/utils')
Expand Down Expand Up @@ -30,8 +31,8 @@ function proxy ({
respondWithErrors
}) {
log.debug('SERVERLESS_EXPRESS:PROXY', {
event,
context,
event: util.inspect(event, { depth: null }),
context: util.inspect(context, { depth: null }),
resolutionMode,
eventSourceName,
binarySettings,
Expand Down
3 changes: 2 additions & 1 deletion src/transport.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const util = require('util')
const ServerlessRequest = require('./request')
const ServerlessResponse = require('./response')
const { getEventSource } = require('./event-sources')
Expand Down Expand Up @@ -37,7 +38,7 @@ function forwardResponse ({
})

log.debug('SERVERLESS_EXPRESS:FORWARD_RESPONSE:EVENT_SOURCE_RESPONSE', {
successResponse,
successResponse: util.inspect(successResponse, { depth: null }),
body: logBody
})

Expand Down

0 comments on commit b15a72c

Please sign in to comment.