Skip to content

Instantly share code, notes, and snippets.

@keepitsimple
Forked from falkolab/download.js
Last active March 6, 2021 15:33
Show Gist options
  • Save keepitsimple/337aebd3143feaa87bfcfcc6b10ba206 to your computer and use it in GitHub Desktop.
Save keepitsimple/337aebd3143feaa87bfcfcc6b10ba206 to your computer and use it in GitHub Desktop.
Download file by http with progress (ES6, promises, NodeJS 12.x)
import fs from 'fs'
import http from 'http'
import { basename } from 'path'
import { URL } from 'url'
const TIMEOUT = 10000
export default function (url, path) {
const uri = new URL(url)
if (!path) {
path = basename(uri.pathname)
}
return new Promise(function (resolve, reject) {
const request = http.get(uri.href).on('response', function (res) {
const len = parseInt(res.headers['content-length'] as string, 10)
let downloaded = 0
let percent = '0.00'
if (res.statusCode !== 200) {
reject(new Error(`Download request failed, response status: ${res.statusCode} ${res.statusMessage}`))
return
}
const file = fs.createWriteStream(path, { flags: 'wx' })
res
.on('data', function (chunk) {
file.write(chunk)
downloaded += chunk.length
percent = (100.0 * downloaded / len).toFixed(2)
process.stdout.write(`Downloading ${percent}% ${downloaded} bytes\r`)
})
.on('end', function () {
file.end()
// console.log(`${uri.pathname} downloaded to: ${path}`)
resolve()
})
.on('error', function (err) {
file.destroy()
// eslint-disable-next-line @typescript-eslint/no-empty-function
fs.unlink(path, () => { })
reject(err)
})
})
request.setTimeout(TIMEOUT, function () {
request.abort()
reject(new Error(`request timeout after ${TIMEOUT / 1000.0}s`))
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment