Files
vercel__next.js/test/unit/image-response-header.test.ts
Untitled 6f0581aff4 Fix ImageResponse headers merging (#67642)
### What?

`ImageResponse` merges default headers and developer-provided headers
incorrectly. The original implementation uses an object-based,
case-sensitive merging strategy, which results in developer-provided
header values being appended after the default header values by the
`Response` (or `Headers`) constructor.

### Why?

`ImageResponse` is used to generate image dynamically. Sometimes the
scenario would be the following. Given a URL without any timestamp, the
developer wants to generate an image depending on a mutable state. For
example, a profile image URL that is to be embedded on blogs by the end
user. In that case, the URL should be stable, and the `max-age` of the
image should be kept short enough because the end user might change
their profile. If the developer passes in a `Cache-Control` header with
any object key other than the fully lower-cased `cache-control`, the
developer's `Cache-Control` value gets **appended** after the default
`Cache-Control` value.

### How?

This PR fixes this by respecting developer-provided headers and
overwriting default ones if the developer has explicitly specified one.

Fixes #67641

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2024-07-26 22:04:19 +00:00

58 lines
1.4 KiB
TypeScript

/* eslint-env jest */
import { ImageResponse } from 'next/og'
import React from 'react'
describe('new ImageResponse()', () => {
const exactHeader = 'public, max-age=3600, s-maxage=3600'
it('should merge object literal headers correctly', () => {
const res = new ImageResponse(
React.createElement(
'div',
{ style: { width: 10, height: 10 } },
'ImageResponse'
),
{
width: 10,
height: 10,
headers: {
'Cache-Control': exactHeader,
},
}
)
expect(res.headers.get('Content-Type')).toBeTruthy()
expect(res.headers.get('Cache-Control')).toBe(exactHeader)
})
it('should merge Headers instance correctly', () => {
const res = new ImageResponse(
React.createElement(
'div',
{ style: { width: 10, height: 10 } },
'ImageResponse'
),
{
width: 10,
height: 10,
headers: new Headers({
'Cache-Control': exactHeader,
}),
}
)
expect(res.headers.get('Content-Type')).toBeTruthy()
expect(res.headers.get('Cache-Control')).toBe(exactHeader)
})
it('should have default Cache-Control header', () => {
const res = new ImageResponse(
React.createElement(
'div',
{ style: { width: 10, height: 10 } },
'ImageResponse'
),
{
width: 10,
height: 10,
}
)
expect(res.headers.get('Cache-Control')).toBeTruthy()
})
})