Skip to content

Commit c862f5a

Browse files
committed
feat: use cacheKey in fetch-remote-file
1 parent af88067 commit c862f5a

File tree

5 files changed

+28
-165
lines changed

5 files changed

+28
-165
lines changed

packages/gatsby-source-contentful/src/gatsby-plugin-image.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-check
22
import fs from "fs-extra"
3-
import { fetchRemoteFile } from "gatsby-core-utils"
3+
import { fetchRemoteFile } from "gatsby-core-utils/fetch-remote-file"
44
import path from "path"
55
import {
66
createUrl,
@@ -61,8 +61,9 @@ export const getBase64Image = (imageProps, cache) => {
6161

6262
const absolutePath = await fetchRemoteFile({
6363
url: requestUrl,
64-
cache,
64+
directory: cache.directory,
6565
ext: extension,
66+
cacheKey: imageProps.image.internal.contentDigest,
6667
})
6768

6869
const base64 = (await fs.readFile(absolutePath)).toString(`base64`)
@@ -97,8 +98,9 @@ const getTracedSVG = async ({ image, options, cache }) => {
9798
const absolutePath = await fetchRemoteFile({
9899
url,
99100
name,
100-
cache,
101+
directory: cache.directory,
101102
ext: extension,
103+
cacheKey: image.internal.contentDigest,
102104
})
103105

104106
return traceSVG({
@@ -147,8 +149,9 @@ const getDominantColor = async ({ image, options, cache }) => {
147149
const absolutePath = await fetchRemoteFile({
148150
url,
149151
name,
150-
cache,
152+
directory: cache.directory,
151153
ext: extension,
154+
cacheKey: image.internal.contentDigest,
152155
})
153156

154157
if (!(`getDominantColor` in pluginSharp)) {

packages/gatsby-source-filesystem/src/create-remote-file-node.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { fetchRemoteFile } = require(`gatsby-core-utils`)
1+
const { fetchRemoteFile } = require(`gatsby-core-utils/fetch-remote-file`)
22
const { isWebUri } = require(`valid-url`)
33
const { createFileNode } = require(`./create-file-node`)
44

packages/gatsby-source-shopify/src/resolve-gatsby-image-data.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { fetchRemoteFile } from "gatsby-core-utils"
1+
import { fetchRemoteFile } from "gatsby-core-utils/fetch-remote-file"
22
import {
33
generateImageData,
44
getLowResolutionImageURL,
@@ -10,22 +10,26 @@ import {
1010
import { IGatsbyImageFieldArgs } from "gatsby-plugin-image/graphql-utils"
1111
import { readFileSync } from "fs"
1212
import { IShopifyImage, urlBuilder } from "./get-shopify-image"
13+
import type { Node } from "gatsby"
1314

1415
type IImageWithPlaceholder = IImage & {
1516
placeholder: string
1617
}
1718

1819
async function getImageBase64({
1920
imageAddress,
20-
cache,
21+
directory,
22+
contentDigest,
2123
}: {
2224
imageAddress: string
23-
cache: any
25+
directory: string
26+
contentDigest: string
2427
}): Promise<string> {
2528
// Downloads file to the site cache and returns the file path for the given image (this is a path on the host system, not a URL)
2629
const filePath = await fetchRemoteFile({
2730
url: imageAddress,
28-
cache,
31+
directory,
32+
cacheKey: contentDigest,
2933
})
3034
const buffer = readFileSync(filePath)
3135
return buffer.toString(`base64`)
@@ -99,7 +103,8 @@ export function makeResolveGatsbyImageData(cache: any) {
99103
})
100104
const imageBase64 = await getImageBase64({
101105
imageAddress: lowResImageURL,
102-
cache,
106+
directory: cache.directory as string,
107+
contentDigest: image.internal.contentDigest,
103108
})
104109

105110
// This would be your own function to download and generate a low-resolution placeholder

packages/gatsby-source-wordpress/src/steps/source-nodes/create-nodes/create-remote-file-node/index.js

Lines changed: 9 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const { isWebUri } = require(`valid-url`)
88
const Queue = require(`better-queue`)
99
const readChunk = require(`read-chunk`)
1010
const fileType = require(`file-type`)
11-
11+
const { fetchRemoteFile } = require(`gatsby-core-utils/fetch-remote-file`)
1212
const { createFileNode } = require(`gatsby-source-filesystem/create-file-node`)
1313
const {
1414
getRemoteFileExtension,
@@ -142,94 +142,6 @@ async function pushToQueue(task, cb) {
142142
/******************
143143
* Core Functions *
144144
******************/
145-
146-
/**
147-
* requestRemoteNode
148-
* --
149-
* Download the requested file
150-
*
151-
* @param {String} url
152-
* @param {Headers} headers
153-
* @param {String} tmpFilename
154-
* @param {Object} httpOpts
155-
* @param {number} attempt
156-
* @return {Promise<Object>} Resolves with the [http Result Object]{@link https://nodejs.org/api/http.html#http_class_http_serverresponse}
157-
*/
158-
const requestRemoteNode = (url, headers, tmpFilename, httpOpts, attempt = 1) =>
159-
new Promise((resolve, reject) => {
160-
let timeout
161-
162-
// Called if we stall without receiving any data
163-
const handleTimeout = async () => {
164-
fsWriteStream.close()
165-
fs.removeSync(tmpFilename)
166-
if (attempt < STALL_RETRY_LIMIT) {
167-
// Retry by calling ourself recursively
168-
resolve(
169-
requestRemoteNode(url, headers, tmpFilename, httpOpts, attempt + 1)
170-
)
171-
} else {
172-
processingCache[url] = null
173-
totalJobs -= 1
174-
bar.total = totalJobs
175-
reject(
176-
new Error(
177-
`Failed to download ${url} after ${STALL_RETRY_LIMIT} attempts`
178-
)
179-
)
180-
}
181-
}
182-
183-
const resetTimeout = () => {
184-
if (timeout) {
185-
clearTimeout(timeout)
186-
}
187-
timeout = setTimeout(handleTimeout, STALL_TIMEOUT)
188-
}
189-
190-
const responseStream = got.stream(url, {
191-
headers,
192-
timeout: { send: CONNECTION_TIMEOUT },
193-
...httpOpts,
194-
})
195-
const fsWriteStream = fs.createWriteStream(tmpFilename)
196-
responseStream.pipe(fsWriteStream)
197-
198-
// If there's a 400/500 response or other error.
199-
responseStream.on(`error`, error => {
200-
if (timeout) {
201-
clearTimeout(timeout)
202-
}
203-
processingCache[url] = null
204-
totalJobs -= 1
205-
bar.total = totalJobs
206-
fs.removeSync(tmpFilename)
207-
console.error(error)
208-
reject(error)
209-
})
210-
211-
fsWriteStream.on(`error`, error => {
212-
if (timeout) {
213-
clearTimeout(timeout)
214-
}
215-
processingCache[url] = null
216-
totalJobs -= 1
217-
bar.total = totalJobs
218-
reject(error)
219-
})
220-
221-
responseStream.on(`response`, response => {
222-
resetTimeout()
223-
224-
fsWriteStream.on(`finish`, () => {
225-
if (timeout) {
226-
clearTimeout(timeout)
227-
}
228-
resolve(response)
229-
})
230-
})
231-
})
232-
233145
/**
234146
* processRemoteNode
235147
* --
@@ -249,71 +161,14 @@ async function processRemoteNode({
249161
ext,
250162
name,
251163
}) {
252-
const pluginCacheDir = cache.directory
253-
// See if there's response headers for this url
254-
// from a previous request.
255-
const cachedHeaders = await cache.get(cacheId(url))
256-
257-
const headers = { ...httpHeaders }
258-
if (cachedHeaders && cachedHeaders.etag) {
259-
headers[`If-None-Match`] = cachedHeaders.etag
260-
}
261-
262-
// Add htaccess authentication if passed in. This isn't particularly
263-
// extensible. We should define a proper API that we validate.
264-
const httpOpts = {}
265-
if (auth?.htaccess_pass && auth?.htaccess_user) {
266-
headers[`Authorization`] = `Basic ${btoa(
267-
`${auth.htaccess_user}:${auth.htaccess_pass}`
268-
)}`
269-
}
270-
271-
// Create the temp and permanent file names for the url.
272-
const digest = createContentDigest(url)
273-
if (!name) {
274-
name = getRemoteFileName(url)
275-
}
276-
if (!ext) {
277-
ext = getRemoteFileExtension(url)
278-
}
279-
280-
const tmpFilename = createFilePath(pluginCacheDir, `tmp-${digest}`, ext)
281-
282-
// Fetch the file.
283-
const response = await requestRemoteNode(url, headers, tmpFilename, httpOpts)
284-
285-
if (response.statusCode == 200) {
286-
// Save the response headers for future requests.
287-
await cache.set(cacheId(url), response.headers)
288-
}
289-
290-
// If the user did not provide an extension and we couldn't get one from remote file, try and guess one
291-
if (ext === ``) {
292-
const buffer = readChunk.sync(tmpFilename, 0, fileType.minimumBytes)
293-
const filetype = fileType(buffer)
294-
if (filetype) {
295-
ext = `.${filetype.ext}`
296-
}
297-
}
298-
299-
const filename = createFilePath(
300-
path.join(pluginCacheDir, digest),
301-
String(name),
302-
ext
303-
)
304-
305-
// If the status code is 200, move the piped temp file to the real name.
306-
if (response.statusCode === 200) {
307-
await fs.move(tmpFilename, filename, { overwrite: true })
308-
// Else if 304, remove the empty response.
309-
} else {
310-
processingCache[url] = null
311-
totalJobs -= 1
312-
313-
bar.total = totalJobs
314-
315-
await fs.remove(tmpFilename)
316-
}
164+
const filename = await fetchRemoteFile({
165+
url,
166+
httpHeaders,
167+
auth,
168+
ext,
169+
name,
170+
directory: cache.directory,
171+
})
317172

318173
// Create the file node.
319174
const fileNode = await createFileNode(filename, createNodeId, {})

packages/gatsby-transformer-sqip/src/extend-node-type.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const {
1212
GraphQLBoolean,
1313
} = require(`gatsby/graphql`)
1414
const { queueImageResizing } = require(`gatsby-plugin-sharp`)
15-
const { fetchRemoteFile } = require(`gatsby-core-utils`)
15+
const { fetchRemoteFile } = require(`gatsby-core-utils/fetch-remote-file`)
1616
const {
1717
DuotoneGradientType,
1818
ImageCropFocusType,

0 commit comments

Comments
 (0)