1

I cannot find anything on neither Documentations nor Google about resumable downloads on Rails (Ruby)

I am using Ruby 2.4 and Rails 5.0.1 on Linux. I want to let my users to download a file over rails. When download starts I want to let them pause and resume it. And, on each requested block I want to execute some functions (events maybe).

I can do that on PHP/Laravel5. I can provide resumable downloads and i can run code on each requested part.

I cannot find anything about this on Rails' website or Google. Is this giant framework not capable of doing it?

Big Note:

I am not talking about directly downloading files. I want to control each part. When from x byte to y byte requested, I want to execute some code before they deliver that part.

Any ideas?

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
Dennis
  • 1,805
  • 3
  • 22
  • 41
  • Possible duplicate of [How to download a file from rails application](http://stackoverflow.com/questions/6392003/how-to-download-a-file-from-rails-application) – Eli Sadoff Jan 19 '17 at 17:50
  • Nope. It just downloads a file. I want to control each chunk/parts and execute some code on request. – Dennis Jan 19 '17 at 17:56
  • 2
    See section 12.3 [Live Streaming in the Rails Guide](http://guides.rubyonrails.org/action_controller_overview.html#streaming-and-file-downloads). – 7stud Jan 19 '17 at 18:12

1 Answers1

2

Streaming

This article and the official documentation are informative.

class DownloadingController < ActionController::Base
  include ActionController::Live

  def stream
    response.headers['Content-Type'] = 'text/event-stream'
    (params[:from].to_i..params[:to].to_i).each { |i|
      response.stream.write "hello world #{i}\n"
      sleep 1
    }
  ensure
    response.stream.close
  end
end

with routes.rb :

get 'downloading' => 'downloading#stream'

Launching :

curl -i "http://localhost:3000/downloading?from=10&to=20"

outputs :

HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/event-stream
ETag: W/"1f373c782d25c8d804203b14291b315b"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 53337282-e382-4807-bdf9-cbf689ac24b2
X-Runtime: 21.048071
Transfer-Encoding: chunked

hello world 10
hello world 11
hello world 12
hello world 13
hello world 14
hello world 15
hello world 16
hello world 17
hello world 18
hello world 19
hello world 20

Resuming

If you want to resume a previous download, you'll have to check request.headers["Range"] and set :status => "206 Partial Content" as well as response.header["Accept-Ranges"] = "bytes".

Those two answers might help you.

Community
  • 1
  • 1
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • 1
    Download accelerators uses `Content-range` header field. So, Instead of GET query parameters like yours (from/to), I can use that header field to parse each requested chunk and send that part of a file to client. – Dennis Jan 19 '17 at 18:42
  • After you updated your answer on 'Resume'. Thank you, That's what I am trying to do. – Dennis Jan 19 '17 at 18:46