Skip to content

Commit

Permalink
feat: add in option to set default headers
Browse files Browse the repository at this point in the history
  • Loading branch information
willfarrell committed Nov 8, 2023
1 parent 9784bfe commit 1e43edc
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 32 deletions.
82 changes: 82 additions & 0 deletions packages/http-header-normalizer/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,47 @@ test('It can use custom normalization function', async (t) => {
t.deepEqual(resultingEvent.rawHeaders, originalHeaders)
})

test('It should normalize (lowercase) all the headers with defaults', async (t) => {
const handler = middy()
.use(
httpHeaderNormalizer({
defaultHeaders: {
'Content-Type': 'application/json',
Accept: '*/*'
}
})
)
.handler((event, context) => event)

const event = {
headers: {
'x-aPi-key': '123456',
tcn: 'abc',
te: 'cde',
DNS: 'd',
FOO: 'bar',
Accept: 'application/json'
}
}

const expectedHeaders = {
'x-api-key': '123456',
tcn: 'abc',
te: 'cde',
dns: 'd',
foo: 'bar',
accept: 'application/json',
'content-type': 'application/json'
}

const originalHeaders = { ...event.headers }

const resultingEvent = await handler(event, context)

t.deepEqual(resultingEvent.headers, expectedHeaders)
t.deepEqual(resultingEvent.rawHeaders, originalHeaders)
})

// multiValueHeaders

test('It should normalize (lowercase) all the headers and create a copy in rawMultiValueHeaders', async (t) => {
Expand Down Expand Up @@ -184,6 +225,47 @@ test('It can use custom normalization function on multiValueHeaders', async (t)
t.deepEqual(resultingEvent.rawMultiValueHeaders, originalHeaders)
})

test('It should normalize (lowercase) all the multiValueHeaders with defaults', async (t) => {
const handler = middy()
.use(
httpHeaderNormalizer({
defaultHeaders: {
'Content-Type': 'application/json',
Accept: '*/*'
}
})
)
.handler((event, context) => event)

const event = {
multiValueHeaders: {
'x-aPi-key': '123456',
tcn: 'abc',
te: 'cde',
DNS: 'd',
FOO: 'bar',
Accept: 'application/json'
}
}

const expectedHeaders = {
'x-api-key': '123456',
tcn: 'abc',
te: 'cde',
dns: 'd',
foo: 'bar',
accept: 'application/json',
'content-type': 'application/json'
}

const originalHeaders = { ...event.multiValueHeaders }

const resultingEvent = await handler(event, context)

t.deepEqual(resultingEvent.multiValueHeaders, expectedHeaders)
t.deepEqual(resultingEvent.rawMultiValueHeaders, originalHeaders)
})

// Misc
test('It should not fail if the event does not contain headers', async (t) => {
const handler = middy((event, context) => event)
Expand Down
5 changes: 3 additions & 2 deletions packages/http-header-normalizer/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import middy from '@middy/core'

interface Options {
normalizeHeaderKey?: (key: string) => string
canonical?: boolean
defaultHeaders?: Record<string, string>
normalizeHeaderKey?: (key: string) => string
}

export interface Event {
rawHeaders: Record<string, string>
}

declare function httpHeaderNormalizer (
declare function httpHeaderNormalizer(
options?: Options
): middy.MiddlewareObj<Event>

Expand Down
11 changes: 9 additions & 2 deletions packages/http-header-normalizer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,23 @@ const normalizeHeaderKey = (key, canonical) => {

const defaults = {
canonical: false,
defaultHeaders: {},
normalizeHeaderKey
}

const httpHeaderNormalizerMiddleware = (opts = {}) => {
const options = { ...defaults, ...opts }

const defaultHeaders = {}
for (const key of Object.keys(options.defaultHeaders)) {
defaultHeaders[options.normalizeHeaderKey(key, options.canonical)] =
options.defaultHeaders[key]
}

const httpHeaderNormalizerMiddlewareBefore = async (request) => {
if (request.event.headers) {
const rawHeaders = {}
const headers = {}
const headers = { ...defaultHeaders }

for (const key of Object.keys(request.event.headers)) {
rawHeaders[key] = request.event.headers[key]
Expand All @@ -75,7 +82,7 @@ const httpHeaderNormalizerMiddleware = (opts = {}) => {

if (request.event.multiValueHeaders) {
const rawHeaders = {}
const headers = {}
const headers = { ...defaultHeaders }

for (const key of Object.keys(request.event.multiValueHeaders)) {
rawHeaders[key] = request.event.multiValueHeaders[key]
Expand Down
19 changes: 0 additions & 19 deletions website/docs/middlewares/http-event-normalizer.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,3 @@ const handler = middy((event, context) => {

handler.use(httpEventNormalizer())
```

## Need to set default `Content-Type` of other missing headers?

```javascript
import middy from '@middy/core'
import httpEventNormalizer from '@middy/http-event-normalizer'

const handler = middy()
.before((request) => {
request.event.headers['Content-Type'] ??= 'application/json'
})
.use(httpEventNormalizer())
.handler((event, context) => {
console.log(`Hello user ${event.pathParameters.userId}`)
// might produce `Hello user undefined`, but not an error

return {}
})
```
16 changes: 7 additions & 9 deletions website/docs/middlewares/http-header-normalizer.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,22 @@ To install this middleware you can use NPM:
npm install --save @middy/http-header-normalizer
```


## Options

- `normalizeHeaderKey` (function) (optional): a function that accepts an header name as a parameter and returns its
- `canonical` (bool) (optional): if true, modifies the headers to canonical format, otherwise the headers are normalized to lowercase (default `false`)
- `defaultHeaders` (object) (optional): Default headers to used if any are missing. i.e. `Content-Type` (default `{}`)
- `normalizeHeaderKey` (function) (optional): a function that accepts an header name as a parameter and returns its
canonical representation.
- `canonical` (bool) (optional): if true, modifies the headers to canonical format, otherwise the headers are normalized to lowercase (default `false`)


## Sample usage

```javascript
import middy from '@middy/core'
import httpHeaderNormalizer from '@middy/http-header-normalizer'

const handler = middy((event, context) => {
return {}
})

handler
const handler = middy()
.use(httpHeaderNormalizer())
.handler((event, context) => {
return {}
})
```

0 comments on commit 1e43edc

Please sign in to comment.