Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Content-Type created file with Ruby File?

I'm using File.open to create a .csv file on the fly.

But what I need to do is set the Content-Type of the file to binary/octet-stream so that the browser will automatically download it instead of just displaying the contents of it in the browser.

The file itself is created locally and then uploaded to Amazon S3.

like image 805
Shpigford Avatar asked Jan 09 '12 17:01

Shpigford


1 Answers

Short Answer

There is no way to specify a Content-Type value in the filesystem when you create your file. In fact, this is probably not the best way to achieve your goal.

In order to suggest that a browser download a file rather than displaying it, you can leave Content-Type: text/csv and add the header Content-Disposition: attachment or Content-Disposition: attachment; filename=<your custom filename>.csv to change the filename in the "Save As..." dialog.

Setting Content-Disposition using Paperclip and AWS::S3

To set the Content-Disposition header using Paperclip, you can add a key to your has_attached_file definition: s3_headers.

has_attached_file :spreadsheet,
  :path => 'perhaps/a/custom/path/:class/:id/:filename',
  :or_maybe => 'other parameters',
  :s3_headers => { 'Content-Disposition' => 'attachment' }

Content-Type issues

By default, a file with the extension .csv should be classified as a text/csv file. You can check this with Mime::Type.lookup_by_extension('csv').to_s # => "text/csv". If this is not the case, you can add text/csv as a custom mime-type by creating a config/initializers/mime_types.rb file and adding:

Mime::Type.register 'text/csv', :csv

However, this should almost always not be the case (unless Windows does something funky with content types; I've only tested in Linux).

Examples

I've put up two examples that you can check. The first is a CSV file uploaded with a text/plain mime-type which forces the browser to show it in-browser without downloading (my browser downloaded text/csv files).

https://s3.amazonaws.com/stackoverflow-demo/demo.csv

The second also has a mime-type of text/plain, but I added a header Content-Disposition: attachment; filename="mycustomname.csv"

https://s3.amazonaws.com/stackoverflow-demo/demo-download.csv

You'll notice that the first link is displayed in browser, while the second link is downloaded with the custom name mycustomname.csv.

To learn why, look at the headers using curl -I.

$ curl -I https://s3.amazonaws.com/stackoverflow-demo/demo-download.csv
HTTP/1.1 200 OK
Content-Disposition: attachment; filename="mycustomname.csv"
Content-Type: text/plain

versus

$ curl -I https://s3.amazonaws.com/stackoverflow-demo/demo.csv
HTTP/1.1 200 OK
Content-Type: text/plain

Note: unrelated headers were removed.

like image 183
Benjamin Manns Avatar answered Sep 30 '22 11:09

Benjamin Manns