Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force a link to download an MP3 rather than play it?

Ive got an anchor link

<a href="http://bucket_name.amazonaws.com/uploads/users/4/songs/7/test.mp3">Download</a> 

How do I make it so when a user clicks on it, it actually opens a popup asking the user to save the file instead of trying to play the file on the browser?

EDIT:

I was reading this article.

  def download
    data = open(Song.first.attachment)
    send_data data.read, :type => data.content_type, :x_sendfile=>true
  end

The article suggest using x_sendfile, since send_file takes up an http process with the potential risk of hanging the app until the download is completed.

Second, I am using send_data instead of send_file, which seems to work if the file is remote (i.e. hosted on Amazon S3). As suggested by this article.

The article, I mentioned was posted on 2009. Is x_sendfile=>true still necessary? Will it hang the app if it isn't included?

Should I really be using send_data or send_file?

like image 501
Christian Fazzini Avatar asked May 13 '11 07:05

Christian Fazzini


3 Answers

You can manage your file downloading with separate controller, if you don't want to eal with HTTP server configurations.

So you can send_file with disposition option as attachment.

like image 134
fl00r Avatar answered Oct 05 '22 22:10

fl00r


Depends on how you / where you serve the file itself. I do not have experience with ruby but if you can alter the headers(most platforms offer this option) of the http response you can force a download. This requires:

Content-Type: application/force-download

I guess it will use "Content-type: application/octet-stream" by default which will cause the browser to play it.

But this will only work if you have control over the server/location that holds the actual file since you need to change the response when the file is sent to the browser.

like image 32
BossJeroen Avatar answered Oct 05 '22 22:10

BossJeroen


Skip The Controller Action

You don't even need the download controller action, you can just generate a download-friendly link like so:

In your attachment.rb

def download_url
  S3 = AWS::S3.new.buckets[ 'bucket_name' ] # This can be done elsewhere as well,
                                            # e.g config/environments/development.rb

  url_options = { 
    expires_in:                   60.minutes, 
    use_ssl:                      true, 
    response_content_disposition: "attachment; filename=\"#{file_name}\""
  }

  S3.objects[ self.path ].url_for( :read, url_options ).to_s
end

In your views

<%= link_to 'Download Avicii by Avicii', attachment.download_url %>

If you still wanted to keep your download action for some reason then just use this:

In your attachments_controller.rb

def download
  redirect_to @attachment.download_url
end

Thanks to guilleva for his guidance.

like image 34
Joshua Pinter Avatar answered Oct 05 '22 23:10

Joshua Pinter