@@ -8,7 +8,7 @@ const { isWebUri } = require(`valid-url`)
88const Queue = require ( `better-queue` )
99const readChunk = require ( `read-chunk` )
1010const fileType = require ( `file-type` )
11-
11+ const { fetchRemoteFile } = require ( `gatsby-core-utils/fetch-remote-file` )
1212const { createFileNode } = require ( `gatsby-source-filesystem/create-file-node` )
1313const {
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 , { } )
0 commit comments