Module Merb::ControllerMixin
In: merb-core/lib/merb-core/controller/mixins/controller.rb

Module that is mixed in to all implemented controllers.

Methods

Public Instance methods

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.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 315
315:     def delete_cookie(name)
316:       set_cookie(name, nil, Merb::Const::COOKIE_EXPIRED_TIME)
317:     end
escape_html(obj)

Alias for escape_xml

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.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 328
328:     def escape_xml(obj)
329:       Merb::Parse.escape_xml(obj.to_s)
330:     end
h(obj)

Alias for escape_xml

Retreives the redirect message either locally or from the request.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 148
148:     def message
149:       @_message = defined?(@_message) ? @_message : request.message
150:     end

Uses the nginx specific +X-Accel-Redirect+ header to send a file directly from nginx.

Notes

Unless Content-Disposition is set before calling this method, it is set to attachment with streamed file name.

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

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

String:precisely a single space.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 281
281:     def nginx_send_file(path, content_type = "")
282:       # Let Nginx detect content type unless it is explicitly set
283:       headers['Content-Type']        = content_type
284:       headers["Content-Disposition"] ||= "attachment; filename=#{path.split('/').last}"
285:       
286:       headers['X-Accel-Redirect']    = path
287:       
288:       return ' '
289:     end

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)

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 132
132:     def redirect(url, opts = {})
133:       default_redirect_options = { :message => nil, :permanent => false }
134:       opts = default_redirect_options.merge(opts)
135:       if opts[:message]
136:         notice = Merb::Parse.escape([Marshal.dump(opts[:message])].pack("m"))
137:         url = url =~ /\?/ ? "#{url}&_message=#{notice}" : "#{url}?_message=#{notice}"
138:       end
139:       self.status = opts[:permanent] ? 301 : 302
140:       Merb.logger.info("Redirecting to: #{url} (#{self.status})")
141:       headers['Location'] = url
142:       "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>"
143:     end

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

:api: public

[Source]

    # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 50
50:     def render_chunked(&blk)
51:       must_support_streaming!
52:       headers['Transfer-Encoding'] = 'chunked'
53:       Proc.new { |response|
54:         @response = response
55:         response.send_status_no_connection_close('')
56:         response.send_header
57:         blk.call
58:         response.write("0\r\n\r\n")
59:       }
60:     end

Parameters

&blk:A proc that should get called outside the mutex, and which will return the value to render.

Returns

Proc:A block that the server can call later, allowing Merb to release the thread lock and render another request.

:api: public

[Source]

    # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 86
86:     def render_deferred(&blk)
87:       Proc.new do |response|
88:         response.write(blk.call)
89:       end
90:     end

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 String to 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.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 104
104:     def render_then_call(str, &blk)
105:       Proc.new do |response|
106:         response.write(str)
107:         blk.call
108:       end
109:     end

Enqueu a block to run in a background thread outside of the request response dispatch

Parameters

&blk:proc to run later

Example

run_later do

  SomeBackgroundTask.run

end

:api: public

[Source]

    # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 17
17:     def run_later(&blk)
18:       Merb.run_later(&blk)
19:     end

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.

:api: public

[Source]

    # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 69
69:     def send_chunk(data)
70:       only_runs_on_mongrel!
71:       @response.write('%x' % data.size + "\r\n")
72:       @response.write(data + "\r\n")
73:     end

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.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 203
203:     def send_data(data, opts={})
204:       opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
205:       disposition = opts[:disposition].dup || 'attachment'
206:       disposition << %(; filename="#{opts[:filename]}") if opts[:filename]
207:       headers.update(
208:         'Content-Type'              => opts[:type].strip,  # fixes a problem with extra '\r' with some browsers
209:         'Content-Disposition'       => disposition,
210:         'Content-Transfer-Encoding' => 'binary'
211:       )
212:       data
213:     end

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.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 170
170:     def send_file(file, opts={})
171:       opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
172:       disposition = opts[:disposition].dup || 'attachment'
173:       disposition << %(; filename="#{opts[:filename] ? opts[:filename] : File.basename(file)}")
174:       headers.update(
175:         'Content-Type'              => opts[:type].strip,  # fixes a problem with extra '\r' with some browsers
176:         'Content-Disposition'       => disposition,
177:         'Content-Transfer-Encoding' => 'binary'
178:       )
179:       Proc.new do |response|
180:         file = File.open(file, 'rb')
181:         while chunk = file.read(16384)
182:           response.write chunk
183:         end
184:         file.close
185:       end
186:     end

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.

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 301
301:     def set_cookie(name, value, expires)
302:       options = expires.is_a?(Hash) ? expires : {:expires => expires}
303:       cookies.set_cookie(name, value, options)
304:     end

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_lines for 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

:api: public

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 239
239:     def stream_file(opts={}, &stream)
240:       opts.update(Merb::Const::DEFAULT_SEND_FILE_OPTIONS.merge(opts))
241:       disposition = opts[:disposition].dup || 'attachment'
242:       disposition << %(; filename="#{opts[:filename]}")
243:       headers.update(
244:         'Content-Type'              => opts[:type].strip,  # fixes a problem with extra '\r' with some browsers
245:         'Content-Disposition'       => disposition,
246:         'Content-Transfer-Encoding' => 'binary',
247:         # Rack specification requires header values to respond to :each
248:         'CONTENT-LENGTH'            => opts[:content_length].to_s
249:       )
250:       Proc.new do |response|
251:         stream.call(response)
252:       end
253:     end

Private Instance methods

Marks an output method that only runs on the Mongrel webserver.

Raises

NotImplemented:The Rack adapter is not mongrel.

:api: private

[Source]

     # File merb-core/lib/merb-core/controller/mixins/controller.rb, line 342
342:     def only_runs_on_mongrel!
343:       unless Merb::Config[:log_stream] == 'mongrel'
344:         raise(Merb::ControllerExceptions::NotImplemented, "Current Rack adapter is not mongrel. cannot support this feature")
345:       end
346:     end

[Validate]