Skip to content

Instantly share code, notes, and snippets.

@everylittlefox
Created December 3, 2022 10:12
Show Gist options
  • Select an option

  • Save everylittlefox/26ad42fcaa3fed4b31a3656041176174 to your computer and use it in GitHub Desktop.

Select an option

Save everylittlefox/26ad42fcaa3fed4b31a3656041176174 to your computer and use it in GitHub Desktop.
an express router that downloads and caches files.
import express from 'express'
import fs from 'fs'
import http from 'http'
import u from 'url'
import path from 'path'
const downloadRouter = express.Router()
let downloadedFiles = {}
downloadRouter.get('/', async (req, res) => {
console.log(downloadedFiles)
const url = new u.URL(req.query.url)
const extension = req.query.ext
const decoded = decodeURI(url.pathname)
if (downloadedFiles[decoded])
return fs.createReadStream(downloadedFiles[decoded]).pipe(res)
downloadedFiles[decoded] = 'files/' + filenameFromUrl(url, extension)
const file = await download(url, downloadedFiles[decoded])
file.pipe(res)
})
const filenameFromUrl = (url, fileExt) => {
const decoded = decodeURI(url.pathname)
const base = path.basename(decoded)
const pathExt = path.extname(decoded)
if (!pathExt) return base.replaceAll(' ', '-').substring(0, 20) + fileExt
return base.split(pathExt)[0].replaceAll(' ', '-').substring(0, 20) + pathExt
}
const download = async (url, destination) => {
console.log('download:', url.toString())
const file = fs.createWriteStream(destination)
await new Promise((resolve, reject) => {
http.get(url, function (response) {
response.pipe(file)
// after download completed close filestream
file.on('finish', () => {
file.close()
resolve()
console.log(decodeURI(url.pathname) + ' downloaded')
})
file.on('error', (e) => reject(err))
})
})
return fs.createReadStream(destination)
}
export default downloadRouter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment