Skip to content

Instantly share code, notes, and snippets.

@paulmand3l
Last active December 31, 2015 19:08
Show Gist options
  • Save paulmand3l/8031163 to your computer and use it in GitHub Desktop.
Save paulmand3l/8031163 to your computer and use it in GitHub Desktop.
Downloading a large file with window XHR so that we can follow redirects/proxies/etc. How to let the user cancel the download?
downloadChunk = (url, start, end) ->
xhr = new window.XMLHttpRequest()
deferred = Q.defer()
xhr.open "GET", url, true
xhr.setRequestHeader "range", "bytes=" + start + '-' + end
xhr.onload = ->
if @status == 200
defer.resolve @response
else
defer.reject new Error "Status code: " + @status
xhr.onerror = (err) ->
defer.reject err
do xhr.send
# Maybe something like this?
deferred.promise.cancel = ->
do xhr.abort
deferred.reject new Error "Download Cancelled"
deferred.promise
util.inherits(XHRBinaryStream, Readable)
XHRBinaryStream = (url) ->
Readable.call this
@index = 0
@chunkSize = 1024 * 1024 * 5 # 5 MB
@_url = url
XHRBinaryStream::_read = (size) ->
chunkSize = size? or @chunkSize
@currentChunkPromise = downloadChunk(@targetUrl, @bytesIndex, @bytesIndex + chunkSize)
@currentChunkPromise.then (data) ->
@bytesIndex += chunkSize
@push data
XHRBinaryStream::cancel = ->
do @currentChunkPromise.cancel
@push null
getToDisk = (url, dest) ->
binaryStream = new XHRBinaryStream url
writeStream = fs.createWriteStream dest
binaryStream.pipe(writeStream)
cancel = ->
do binaryStream.unpipe
do binaryStream.cancel
do writeStream.end
fs.unlinkSync dest
canceller = getToDisk('http://www.google.com/robots.txt', 'foo')
setTimeout(canceller, 100);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment