Module: Merb::ControllerMixin

Included in:
Controller
Defined in:
merb-core/lib/merb-core/controller/mixins/controller.rb

Overview

Module that is mixed in to all implemented controllers.

Instance Method Summary (collapse)

Instance Method Details

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.



307
308
309
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 307

def delete_cookie(name)
  set_cookie(name, nil, Merb::Const::COOKIE_EXPIRED_TIME)
end

- (String) escape_xml(obj) Also known as: h, escape_html

Escapes the string representation of obj and escapes it for use in XML.

Parameters:

  • obj (#to_s)

    The object to escape for use in XML.

Returns:

  • (String)

    The escaped object.



318
319
320
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 318

def escape_xml(obj)
  Merb::Parse.escape_xml(obj.to_s)
end

- (Object) message

Retreives the redirect message either locally or from the request.



149
150
151
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 149

def message
  @_message = defined?(@_message) ? @_message : request.message
end

- (String) nginx_send_file(path, content_type = "")

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

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

For more information, see:

Parameters:

  • path (String)

    Path to file to send to the client.

  • content_type (String) (defaults to: "")

    content type header value. By default is set to empty string to let Nginx detect it.

Returns:

  • (String)

    Precisely a single space.



274
275
276
277
278
279
280
281
282
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 274

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

- (String) redirect(url, opts = {})

Returns 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)
redirect("/posts/34", :notice => 'Post updated successfully!')

Parameters:

  • url (String)

    URL to redirect to. It can be either a relative or fully-qualified URL.

  • opts (Hash) (defaults to: {})

    An options hash

Options Hash (opts):

  • :message (Hash) — default: nil

    Messages to pass in url query string as value for "_message"

  • :permanent (Boolean) — default: false

    When true, return status 301 Moved Permanently

  • :notice (String)

    Shorthand for common usage :message => {:notice => "..."}

  • :error (String)

    Shorthand for common usage :message => {:error => "..."}

  • :success (String)

    Shorthand for common usage :message => {:success => "..."}

  • :status (String, Symbol)

    Status code to set for the response. Can be any valid redirect status. Has precedence over the :permanent parameter, which is retained for convenience.

Returns:

  • (String)

    Explanation of redirect.



131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 131

def redirect(url, opts = {})
  default_redirect_options = { :message => nil, :permanent => false }
  opts = default_redirect_options.merge(opts)

  url = handle_redirect_messages(url,opts)

  _status   = opts[:status] if opts[:status]
  _status ||= opts[:permanent] ? 301 : 302
  self.status = _status

  Merb.logger.info("Redirecting to: #{url} (#{self.status})")
  headers['Location'] = url
  "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>"
end

- (Object) render_chunked(&blk)

Renders the block given as a parameter using chunked encoding.

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

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.



48
49
50
51
52
53
54
55
56
57
58
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 48

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

- (Proc) render_deferred(&blk)

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

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.



79
80
81
82
83
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 79

def render_deferred(&blk)
  Proc.new do |response|
    response.write(blk.call)
  end
end

- (Proc) render_then_call(str, &blk)

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.



96
97
98
99
100
101
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 96

def render_then_call(str, &blk)
  Proc.new do |response|
    response.write(str)
    blk.call
  end
end

- (Object) run_later(&blk)

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

Examples:

run_later do
  SomeBackgroundTask.run
end

Parameters:

  • &blk

    proc to run later



16
17
18
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 16

def run_later(&blk)
  Merb.run_later(&blk)
end

- (Object) send_chunk(data)

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.



66
67
68
69
70
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 66

def send_chunk(data)
  only_runs_on_mongrel!
  @response.write('%x' % data.size + "\r\n")
  @response.write(data + "\r\n")
end

- (String) send_data(data, opts = {})

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)

    Raw data to send as a file.

  • opts (Hash) (defaults to: {})

    Options for sending the data.

Options Hash (opts):

  • :disposition (String) — default: "attachment"

    The disposition of the file send.

  • :filename (String)

    The name to use for the file.

  • :type (String)

    The content type.

Returns:

  • (String)

    The raw data passed in.



204
205
206
207
208
209
210
211
212
213
214
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 204

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

- (IO) send_file(file, opts = {})

TODO:

Docs, correctness: is the return type correct?

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) (defaults to: {})

    Options for sending the file.

Options Hash (opts):

  • :disposition (String) — default: "attachment"

    The disposition of the file send.

  • :filename (String) — default: File.basename(file)

    The name to use for the file.

  • :type (String)

    The content type.

Returns:

  • (IO)

    An I/O stream for the file.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 169

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 do |response|
    file = File.open(file, 'rb')
    while chunk = file.read(16384)
      response.write chunk
    end
    file.close
  end
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.



294
295
296
297
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 294

def set_cookie(name, value, expires)
  options = expires.is_a?(Hash) ? expires : {:expires => expires}
  cookies.set_cookie(name, value, options)
end

- (Object) stream_file(opts = {}, &stream)

Streams a file over HTTP.

Examples:

Use with Amazon S3:

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

Parameters:

  • opts (Hash) (defaults to: {})

    Options for the file streaming.

  • &stream

    A block that, when called, will return an object that responds to #get_lines for streaming.

Options Hash (opts):

  • :disposition (String) — default: "attachment"

    The disposition of the file send.

  • :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.



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'merb-core/lib/merb-core/controller/mixins/controller.rb', line 239

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 do |response|
    stream.call(response)
  end
end