Skip to content

Commit

Permalink
🎉 Add support for ALB integrations
Browse files Browse the repository at this point in the history
  • Loading branch information
LinusU committed Oct 20, 2022
1 parent 96f5263 commit cfd66d8
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
50 changes: 41 additions & 9 deletions entrypoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import stream from 'node:stream'

const kChunks = Symbol('chunks')
const kCallback = Symbol('callback')
const kFromLoadBalancer = Symbol('loadBalancer')

function shouldBase64Encode (headers) {
/* Every other content-encoding than "identity" is higlhy likely to be binary */
Expand All @@ -25,6 +26,20 @@ function shouldBase64Encode (headers) {
return true
}

function createMultipleHeaderValues (headers) {
const result = Object.create(null)

for (const key in headers) {
if (headers[key] instanceof Array) {
result[key] = headers[key]
} else {
result[key] = [headers[key]]
}
}

return result
}

function extractMultipleHeaderValues (headers) {
const result = Object.create(null)

Expand All @@ -42,7 +57,9 @@ class LambdaSocket extends stream.Duplex {
constructor (event) {
super()

const sourceIp = event.requestContext.identity.sourceIp
this[kFromLoadBalancer] = (event.requestContext.elb != null)

const sourceIp = event.requestContext.identity?.sourceIp ?? '127.0.0.1'
const sourceFamily = net.isIPv6(sourceIp) ? 'IPv6' : 'IPv4'

this.bufferSize = 0
Expand Down Expand Up @@ -139,14 +156,29 @@ class LambdaResponse extends http.ServerResponse {

const headers = this.getHeaders()
const base64Encode = shouldBase64Encode(headers)
const multiValueHeaders = extractMultipleHeaderValues(headers)

const result = {
isBase64Encoded: base64Encode,
statusCode: this.statusCode,
headers,
multiValueHeaders,
body: Buffer.concat(this[kChunks]).toString(base64Encode ? 'base64' : 'utf8')
const body = Buffer.concat(this[kChunks]).toString(base64Encode ? 'base64' : 'utf8')

let result
if (this.socket[kFromLoadBalancer]) {
const multiValueHeaders = createMultipleHeaderValues(headers)

result = {
isBase64Encoded: base64Encode,
statusCode: this.statusCode,
statusDescription: `${this.statusCode} ${this.statusMessage}`,
multiValueHeaders,
body
}
} else {
const multiValueHeaders = extractMultipleHeaderValues(headers)

result = {
isBase64Encoded: base64Encode,
statusCode: this.statusCode,
headers,
multiValueHeaders,
body
}
}

this.emit('finish')
Expand Down
6 changes: 6 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ scandium update --name=my-awesome-api

By default, Scandium will set up an API Gateway that simply forwards all requests to the Lambda function. If you want to utilise the benefits of API Gateway fully, you can provide a Swagger file describing your API endpoints. Pass the `--swagger=my-api-definition.yml` to either the `create` or `update` command and Scandium will configure the API Gateway for you.

## Application Load Balancer

The deployed entrypoint has support for being called from an application load balancer, as well as API Gateway. Note that "Multi value headers" must be turned on in the load balancer target group for this to work.

There is currently no support in the Scandium CLI to automatically setup an ALB for you.

## `prepare`/`build`-scripts

Scandium has support for `prepare`/`build` scripts, if the script is present in the `package.json` it will make sure that the script is being run with full `devDependencies` installed. The final package being uploaded to Lambda will still only contain the production `dependencies`.
Expand Down

0 comments on commit cfd66d8

Please sign in to comment.