mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
6f0581aff4
### 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>
58 lines
1.4 KiB
TypeScript
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()
|
|
})
|
|
})
|