Module: Merb::ControllerMixin
- Included in:
- Controller
- Defined in:
- lib/merb-core/controller/mixins/controller.rb
Overview
Module that is mixed in to all implemented controllers.
Instance Method Summary collapse
-
#delete_cookie(name) ⇒ Object
Marks a cookie as deleted and gives it an expires stamp in the past.
-
#escape_xml(obj) ⇒ Object
(also: #h, #escape_html)
Escapes the string representation of
objand escapes it for use in XML. - #message ⇒ Object
-
#nginx_send_file(path, content_type = "") ⇒ Object
Uses the nginx specific
X-Accel-Redirectheader to send a file directly from nginx. -
#redirect(url, opts = {}) ⇒ Object
Parameters url<String>:: URL to redirect to.
-
#render_chunked(&blk) ⇒ Object
Renders the block given as a parameter using chunked encoding.
-
#render_deferred(&blk) ⇒ Object
Parameters &blk:: A proc that should get called outside the mutex, and which will return the value to render.
-
#render_then_call(str, &blk) ⇒ Object
Renders the passed in string, then calls the block outside the mutex and after the string has been returned to the client.
-
#run_later(&blk) ⇒ Object
Enqueu a block to run in a background thread outside of the request response dispatch.
-
#send_chunk(data) ⇒ Object
Writes a chunk from
render_chunkedto the response that is sent back to the client. -
#send_data(data, opts = {}) ⇒ Object
Send binary data over HTTP to the user as a file download.
-
#send_file(file, opts = {}) ⇒ Object
Sends a file over HTTP.
-
#set_cookie(name, value, expires) ⇒ Object
Sets a cookie to be included in the response.
-
#stream_file(opts = {}, &stream) ⇒ Object
Streams a file over HTTP.
Instance Method Details
#delete_cookie(name) ⇒ Object
Marks a cookie as deleted and gives it an expires stamp in the past. This method is used primarily internally in Merb.
Use the cookies hash to manipulate cookies instead.
Parameters
- name<~to_s>
-
A name for the cookie to delete.
288 289 290 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 288 def (name) (name, nil, Merb::Const::COOKIE_EXPIRED_TIME) end |
#escape_xml(obj) ⇒ Object Also known as: h, escape_html
Escapes the string representation of obj and escapes it for use in XML.
Parameter
- obj<~to_s>
-
The object to escape for use in XML.
Returns
- String
-
The escaped object.
299 300 301 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 299 def escape_xml(obj) Erubis::XmlHelper.escape_xml(obj.to_s) end |
#message ⇒ Object
134 135 136 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 134 def = defined?() ? : request. end |
#nginx_send_file(path, content_type = "") ⇒ Object
Uses the nginx specific X-Accel-Redirect header to send a file directly from nginx. For more information, see the nginx wiki: wiki.codemongers.com/NginxXSendfile
and the following sample gist: gist.github.com/11225
there’s also example application up on GitHub:
github.com/michaelklishin/nginx-x-accel-redirect-example-application/tree/master
Unless Content-Disposition is set before calling this method, it is set to attachment with streamed file name.
Parameters
- path<String>
-
Path to file to send to the client.
- content_type<String>
-
content type header value. By default is set to empty string to let Nginx detect it.
Return
One space string.
256 257 258 259 260 261 262 263 264 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 256 def nginx_send_file(path, content_type = "") # Let Nginx detect content type unless it is explicitly set headers['Content-Type'] = content_type headers["Content-Disposition"] ||= "attachment; filename=#{path.split('/').last}" headers['X-Accel-Redirect'] = path return ' ' end |
#redirect(url, opts = {}) ⇒ Object
Parameters
- url<String>
-
URL to redirect to. It can be either a relative or fully-qualified URL.
- opts<Hash>
-
An options hash (see below)
Options (opts)
- :message<Hash>
-
Messages to pass in url query string as value for “_message”
- :permanent<Boolean>
-
When true, return status 301 Moved Permanently
Returns
- String
-
Explanation of redirect.
Examples
redirect("/posts/34")
redirect("/posts/34", :message => { :notice => 'Post updated successfully!' })
redirect("http://www.merbivore.com/")
redirect("http://www.merbivore.com/", :permanent => true)
121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 121 def redirect(url, opts = {}) = { :message => nil, :permanent => false } opts = .merge(opts) if opts[:message] notice = Merb::Request.escape([Marshal.dump(opts[:message])].pack("m")) url = url =~ /\?/ ? "#{url}&_message=#{notice}" : "#{url}?_message=#{notice}" end self.status = opts[:permanent] ? 301 : 302 Merb.logger.info("Redirecting to: #{url} (#{self.status})") headers['Location'] = url "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>" end |
#render_chunked(&blk) ⇒ Object
Renders the block given as a parameter using chunked encoding.
Parameters
- &blk
-
A block that, when called, will use send_chunks to send chunks of data down to the server. The chunking will terminate once the block returns.
Examples
def stream
prefix = '<p>'
suffix = "</p>\r\n"
render_chunked do
IO.popen("cat /tmp/test.log") do |io|
done = false
until done
sleep 0.3
line = io.gets.chomp
if line == 'EOF'
done = true
else
send_chunk(prefix + line + suffix)
end
end
end
end
end
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 47 def render_chunked(&blk) must_support_streaming! headers['Transfer-Encoding'] = 'chunked' Proc.new { |response| @response = response response.send_status_no_connection_close('') response.send_header blk.call response.write("0\r\n\r\n") } end |
#render_deferred(&blk) ⇒ Object
Parameters
- &blk
-
A proc that should get called outside the mutex, and which will return the value to render.
Returns
- Proc
-
A block that Mongrel can call later, allowing Merb to release the thread lock and render another request.
79 80 81 82 83 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 79 def render_deferred(&blk) Proc.new {|response| response.write(blk.call) } end |
#render_then_call(str, &blk) ⇒ Object
Renders the passed in string, then calls the block outside the mutex and after the string has been returned to the client.
Parameters
- str<String>
-
A
Stringto return to the client. - &blk
-
A block that should get called once the string has been returned.
Returns
- Proc
-
A block that Mongrel can call after returning the string to the user.
95 96 97 98 99 100 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 95 def render_then_call(str, &blk) Proc.new {|response| response.write(str) blk.call } end |
#run_later(&blk) ⇒ Object
Enqueu a block to run in a background thread outside of the request response dispatch
Parameters
takes a block to run later
Example
run_later do
SomeBackgroundTask.run
end
16 17 18 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 16 def run_later(&blk) Merb::Dispatcher.work_queue << blk end |
#send_chunk(data) ⇒ Object
Writes a chunk from render_chunked to the response that is sent back to the client. This should only be called within a render_chunked block.
Parameters
- data<String>
-
a chunk of data to return.
64 65 66 67 68 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 64 def send_chunk(data) only_runs_on_mongrel! @response.write('%x' % data.size + "\r\n") @response.write(data + "\r\n") end |
#send_data(data, opts = {}) ⇒ Object
Send binary data over HTTP to the user as a file download. May set content type, apparent file name, and specify whether to show data inline or download as an attachment.
Parameters
- data<String>
-
Path to file to send to the client.
- opts<Hash>
-
Options for sending the data (see below).
Options (opts)
- :disposition<String>
-
The disposition of the file send. Defaults to “attachment”.
- :filename<String>
-
The name to use for the file. Defaults to the filename of file.
- :type<String>
-
The content type.
185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 185 def send_data(data, opts={}) opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts)) disposition = opts[:disposition].dup || 'attachment' disposition << %(; filename="#{opts[:filename]}") if opts[:filename] headers.update( 'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers 'Content-Disposition' => disposition, 'Content-Transfer-Encoding' => 'binary' ) data end |
#send_file(file, opts = {}) ⇒ Object
Sends a file over HTTP. When given a path to a file, it will set the right headers so that the static file is served directly.
Parameters
- file<String>
-
Path to file to send to the client.
- opts<Hash>
-
Options for sending the file (see below).
Options (opts)
- :disposition<String>
-
The disposition of the file send. Defaults to “attachment”.
- :filename<String>
-
The name to use for the file. Defaults to the filename of file.
- :type<String>
-
The content type.
Returns
- IO
-
An I/O stream for the file.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 154 def send_file(file, opts={}) opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts)) disposition = opts[:disposition].dup || 'attachment' disposition << %(; filename="#{opts[:filename] ? opts[:filename] : File.basename(file)}") headers.update( 'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers 'Content-Disposition' => disposition, 'Content-Transfer-Encoding' => 'binary' ) Proc.new {|response| file = File.open(file, 'rb') while chunk = file.read(16384) response.write chunk end file.close } end |
#set_cookie(name, value, expires) ⇒ Object
Sets a cookie to be included in the response.
If you need to set a cookie, then use the cookies hash.
Parameters
- name<~to_s>
-
A name for the cookie.
- value<~to_s>
-
A value for the cookie.
- expires<~gmtime:~strftime, Hash>
-
An expiration time for the cookie, or a hash of cookie options.
276 277 278 279 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 276 def (name, value, expires) = expires.is_a?(Hash) ? expires : {:expires => expires} .(name, value, ) end |
#stream_file(opts = {}, &stream) ⇒ Object
Streams a file over HTTP.
Parameters
- opts<Hash>
-
Options for the file streaming (see below).
- &stream
-
A block that, when called, will return an object that responds to
get_linesfor streaming.
Options
- :disposition<String>
-
The disposition of the file send. Defaults to “attachment”.
- :type<String>
-
The content type.
- :content_length<Numeric>
-
The length of the content to send.
- :filename<String>
-
The name to use for the streamed file.
Examples
stream_file({ :filename => file_name, :type => content_type,
:content_length => content_length }) do |response|
AWS::S3::S3Object.stream(user.folder_name + "-" + user_file.unique_id, bucket_name) do |chunk|
response.write chunk
end
end
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/merb-core/controller/mixins/controller.rb', line 219 def stream_file(opts={}, &stream) opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts)) disposition = opts[:disposition].dup || 'attachment' disposition << %(; filename="#{opts[:filename]}") headers.update( 'Content-Type' => opts[:type].strip, # fixes a problem with extra '\r' with some browsers 'Content-Disposition' => disposition, 'Content-Transfer-Encoding' => 'binary', # Rack specification requires header values to respond to :each 'CONTENT-LENGTH' => opts[:content_length].to_s ) Proc.new{|response| stream.call(response) } end |