Skip to content

Commit 734ff16

Browse files
authored
fix(gatsby-core-utils): handle 304 correctly between builds (#33975)
1 parent b792a4f commit 734ff16

File tree

2 files changed

+88
-7
lines changed

2 files changed

+88
-7
lines changed

packages/gatsby-core-utils/src/__tests__/fetch-remote-file.js

+80-3
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,28 @@ const server = setupServer(
118118
)
119119

120120
return res(
121-
ctx.set(`Content-Type`, `image/svg+xml`),
121+
ctx.set(`Content-Type`, `image/jpg`),
122122
ctx.set(`Content-Length`, contentLength),
123123
ctx.status(200),
124124
ctx.body(content)
125125
)
126126
}),
127+
rest.get(`http://external.com/dog-304.jpg`, async (req, res, ctx) => {
128+
const { content, contentLength } = await getFileContent(
129+
path.join(__dirname, `./fixtures/dog-thumbnail.jpg`),
130+
req
131+
)
132+
133+
// console.log(req.headers)
134+
135+
return res(
136+
ctx.set(`Content-Type`, `image/jpg`),
137+
ctx.set(`Content-Length`, contentLength),
138+
ctx.set(`etag`, `abcd`),
139+
ctx.status(req.headers.get(`if-none-match`) === `abcd` ? 304 : 200),
140+
ctx.body(content)
141+
)
142+
}),
127143
rest.get(`http://external.com/404.jpg`, async (req, res, ctx) => {
128144
const content = `Page not found`
129145

@@ -249,7 +265,7 @@ describe(`fetch-remote-file`, () => {
249265
jest.useRealTimers()
250266
})
251267

252-
it(`downloads and create a file`, async () => {
268+
it(`downloads and create a svg file`, async () => {
253269
const filePath = await fetchRemoteFile({
254270
url: `http://external.com/logo.svg`,
255271
cache,
@@ -272,7 +288,7 @@ describe(`fetch-remote-file`, () => {
272288
expect(gotStream).toBeCalledTimes(1)
273289
})
274290

275-
it(`downloads and create a file`, async () => {
291+
it(`downloads and create a jpg file`, async () => {
276292
const filePath = await fetchRemoteFile({
277293
url: `http://external.com/dog.jpg`,
278294
cache,
@@ -412,6 +428,35 @@ describe(`fetch-remote-file`, () => {
412428
expect(fsMove).toBeCalledTimes(2)
413429
})
414430

431+
it(`handles 304 responses correctly in different builds`, async () => {
432+
const cacheInternals = new Map()
433+
const workerCache = {
434+
get(key) {
435+
return Promise.resolve(cacheInternals.get(key))
436+
},
437+
set(key, value) {
438+
return Promise.resolve(cacheInternals.set(key, value))
439+
},
440+
directory: cache.directory,
441+
}
442+
443+
global.__GATSBY = { buildId: `1` }
444+
const filePath = await fetchRemoteFile({
445+
url: `http://external.com/dog-304.jpg`,
446+
cache: workerCache,
447+
})
448+
449+
global.__GATSBY = { buildId: `2` }
450+
const filePathCached = await fetchRemoteFile({
451+
url: `http://external.com/dog-304.jpg`,
452+
cache: workerCache,
453+
})
454+
455+
expect(filePathCached).toBe(filePath)
456+
expect(fsMove).toBeCalledTimes(1)
457+
expect(gotStream).toBeCalledTimes(2)
458+
})
459+
415460
it(`doesn't keep lock when file download failed`, async () => {
416461
const cacheInternals = new Map()
417462
const workerCache = {
@@ -562,6 +607,38 @@ describe(`fetch-remote-file`, () => {
562607
expect(fsMove).toBeCalledTimes(1)
563608
})
564609

610+
it(`handles 304 responses correctly in different builds and workers`, async () => {
611+
const cacheInternals = new Map()
612+
const workerCache = {
613+
get(key) {
614+
return Promise.resolve(cacheInternals.get(key))
615+
},
616+
set(key, value) {
617+
return Promise.resolve(cacheInternals.set(key, value))
618+
},
619+
directory: cache.directory,
620+
}
621+
622+
const fetchRemoteFileInstanceOne = getFetchInWorkerContext(`1`)
623+
const fetchRemoteFileInstanceTwo = getFetchInWorkerContext(`2`)
624+
625+
global.__GATSBY = { buildId: `1` }
626+
const filePath = await fetchRemoteFileInstanceOne({
627+
url: `http://external.com/dog-304.jpg`,
628+
cache: workerCache,
629+
})
630+
631+
global.__GATSBY = { buildId: `2` }
632+
const filePathCached = await fetchRemoteFileInstanceTwo({
633+
url: `http://external.com/dog-304.jpg`,
634+
cache: workerCache,
635+
})
636+
637+
expect(filePathCached).toBe(filePath)
638+
expect(fsMove).toBeCalledTimes(1)
639+
expect(gotStream).toBeCalledTimes(2)
640+
})
641+
565642
it(`fails when 404 is triggered`, async () => {
566643
await expect(
567644
fetchRemoteFile({

packages/gatsby-core-utils/src/fetch-remote-file.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ async function fetchFile({
164164

165165
// See if there's response headers for this url
166166
// from a previous request.
167-
const cachedHeaders = await cache.get(cacheIdForHeaders(url))
168-
167+
const { headers: cachedHeaders, digest: originalDigest } =
168+
(await cache.get(cacheIdForHeaders(url))) ?? {}
169169
const headers = { ...httpHeaders }
170170
if (cachedHeaders && cachedHeaders.etag) {
171171
headers[`If-None-Match`] = cachedHeaders.etag
@@ -207,7 +207,10 @@ async function fetchFile({
207207

208208
if (response.statusCode === 200) {
209209
// Save the response headers for future requests.
210-
await cache.set(cacheIdForHeaders(url), response.headers)
210+
await cache.set(cacheIdForHeaders(url), {
211+
headers: response.headers,
212+
digest,
213+
})
211214

212215
// If the user did not provide an extension and we couldn't get one from remote file, try and guess one
213216
if (!ext) {
@@ -240,10 +243,11 @@ async function fetchFile({
240243

241244
// If the status code is 200, move the piped temp file to the real name.
242245
const filename = createFilePath(
243-
path.join(pluginCacheDir, digest),
246+
path.join(pluginCacheDir, originalDigest ?? digest),
244247
name,
245248
ext as string
246249
)
250+
247251
if (response.statusCode === 200) {
248252
await fs.move(tmpFilename, filename, { overwrite: true })
249253
// Else if 304, remove the empty response.

0 commit comments

Comments
 (0)