Froze rails gems
[depot.git] / vendor / rails / railties / doc / guides / source / actioncontroller_basics / streaming.txt
1 == Streaming and File Downloads ==
2
3 Sometimes you may want to send a file to the user instead of rendering an HTML page. All controllers in Rails have the `send_data` and the `send_file` methods, that will both stream data to the client. `send_file` is a convenience method which lets you provide the name of a file on the disk and it will stream the contents of that file for you.
4
5 To stream data to the client, use `send_data`:
6
7 [source, ruby]
8 ----------------------------
9 require "prawn"
10 class ClientsController < ApplicationController
11
12 # Generate a PDF document with information on the client and return it.
13 # The user will get the PDF as a file download.
14 def download_pdf
15 client = Client.find(params[:id])
16 send_data(generate_pdf, :filename => "#{client.name}.pdf", :type => "application/pdf")
17 end
18
19 private
20
21 def generate_pdf(client)
22 Prawn::Document.new do
23 text client.name, :align => :center
24 text "Address: #{client.address}"
25 text "Email: #{client.email}"
26 end.render
27 end
28
29 end
30 ----------------------------
31
32 The `download_pdf` action in the example above will call a private method which actually generates the file (a PDF document) and returns it as a string. This string will then be streamed to the client as a file download and a filename will be suggested to the user. Sometimes when streaming files to the user, you may not want them to download the file. Take images, for example, which can be embedded into HTML pages. To tell the browser a file is not meant to be downloaded, you can set the `:disposition` option to "inline". The opposite and default value for this option is "attachment".
33
34 === Sending Files ===
35
36 If you want to send a file that already exists on disk, use the `send_file` method. This is usually not recommended, but can be useful if you want to perform some authentication before letting the user download the file.
37
38 [source, ruby]
39 ----------------------------
40 class ClientsController < ApplicationController
41
42 # Stream a file that has already been generated and stored on disk
43 def download_pdf
44 client = Client.find(params[:id])
45 send_data("#{RAILS_ROOT}/files/clients/#{client.id}.pdf", :filename => "#{client.name}.pdf", :type => "application/pdf")
46 end
47
48 end
49 ----------------------------
50
51 This will read and stream the file 4Kb at the time, avoiding loading the entire file into memory at once. You can turn off streaming with the `:stream` option or adjust the block size with the `:buffer_size` option.
52
53 WARNING: Be careful when using (or just don't use) "outside" data (params, cookies, etc) to locate the file on disk, as this is a security risk that might allow someone to gain access to files they are not meant to see.
54
55 TIP: It is not recommended that you stream static files through Rails if you can instead keep them in a public folder on your web server. It is much more efficient to let the user download the file directly using Apache or another web server, keeping the request from unnecessarily going through the whole Rails stack.
56
57 === RESTful Downloads ===
58
59 While `send_data` works just fine, if you are creating a RESTful application having separate actions for file downloads is usually not necessary. In REST terminology, the PDF file from the example above can be considered just another representation of the client resource. Rails provides an easy and quite sleek way of doing "RESTful downloads". Here's how you can rewrite the example so that the PDF download is a part of the `show` action, without any streaming:
60
61 [source, ruby]
62 ----------------------------
63 class ClientsController < ApplicationController
64
65 # The user can request to receive this resource as HTML or PDF.
66 def show
67 @client = Client.find(params[:id])
68
69 respond_to do |format|
70 format.html
71 format.pdf{ render :pdf => generate_pdf(@client) }
72 end
73 end
74
75 end
76 ----------------------------
77
78 In order for this example to work, you have to add the PDF MIME type to Rails. This can be done by adding the following line to the file `config/initializers/mime_types.rb`:
79
80 [source, ruby]
81 ----------------------------
82 Mime::Type.register "application/pdf", :pdf
83 ----------------------------
84
85 NOTE: Configuration files are not reloaded on each request, so you have to restart the server in order for their changes to take effect.
86
87 Now the user can request to get a PDF version of a client just by adding ".pdf" to the URL:
88
89 ----------------------------
90 GET /clients/1.pdf
91 ----------------------------