mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
fix: coerce HEAD to GET for internal images (#84180)
Fixes: https://github.com/vercel/next.js/issues/84129 TODO: - [x] e2e test (?) - [x] verify against repro steps in source issue --------- Co-authored-by: Steven <[email protected]> Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Steven
vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
parent
f1a047fd80
commit
ab4b3726ea
@@ -900,9 +900,12 @@ export async function fetchInternalImage(
|
||||
) => Promise<void>
|
||||
): Promise<ImageUpstream> {
|
||||
try {
|
||||
// Coerce HEAD to GET to avoid issues with the image optimizer
|
||||
const method = !_req.method || _req.method === 'HEAD' ? 'GET' : _req.method
|
||||
|
||||
const mocked = createRequestResponseMocks({
|
||||
url: href,
|
||||
method: _req.method || 'GET',
|
||||
method,
|
||||
socket: _req.socket,
|
||||
})
|
||||
|
||||
@@ -1193,7 +1196,12 @@ export function sendResponse(
|
||||
)
|
||||
if (!result.finished) {
|
||||
res.setHeader('Content-Length', Buffer.byteLength(buffer))
|
||||
res.end(buffer)
|
||||
// A response body must not be sent for HEAD requests
|
||||
if (req.method === 'HEAD') {
|
||||
res.end()
|
||||
} else {
|
||||
res.end(buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { nextTestSetup } from 'e2e-utils'
|
||||
import fs from 'fs-extra'
|
||||
import { join } from 'path'
|
||||
|
||||
describe('app dir - next-image', () => {
|
||||
const { next, skipped } = nextTestSetup({
|
||||
@@ -11,6 +13,36 @@ describe('app dir - next-image', () => {
|
||||
}
|
||||
|
||||
describe('ssr content', () => {
|
||||
it('should handle HEAD requests for uncached images', async () => {
|
||||
const imagesDir = join(next.testDir, '.next/cache/images')
|
||||
await fs.remove(imagesDir).catch(() => {})
|
||||
|
||||
const $ = await next.render$('/')
|
||||
const imageUrl = $('#app-layout').attr('src')
|
||||
|
||||
const headRes = await next.fetch(imageUrl, { method: 'HEAD' })
|
||||
expect(headRes.status).toBe(200)
|
||||
expect(headRes.headers.get('content-type')).toMatch(/^image\//)
|
||||
expect(headRes.headers.get('X-Nextjs-Cache')).toBe('MISS')
|
||||
|
||||
const contentLength = headRes.headers.get('content-length')
|
||||
expect(Number(contentLength || '0')).toBeGreaterThan(0)
|
||||
const headBody = await headRes.arrayBuffer()
|
||||
expect(headBody.byteLength).toBe(0)
|
||||
|
||||
const getRes = await next.fetch(imageUrl)
|
||||
expect(getRes.status).toBe(200)
|
||||
expect(getRes.headers.get('content-type')).toMatch(/^image\//)
|
||||
expect(getRes.headers.get('X-Nextjs-Cache')).toBe('HIT')
|
||||
|
||||
const getContentLength = getRes.headers.get('content-length')
|
||||
expect(Number(getContentLength || '0')).toBeGreaterThan(0)
|
||||
|
||||
const getBody = await getRes.arrayBuffer()
|
||||
expect(getBody.byteLength).toBeGreaterThan(0)
|
||||
expect(getBody.byteLength).toBe(Number(getContentLength))
|
||||
})
|
||||
|
||||
it('should render images on / route', async () => {
|
||||
const $ = await next.render$('/')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user