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

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.



262
263
264
# File 'lib/merb-core/controller/mixins/controller.rb', line 262

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

#escape_xml(obj) ⇒ Object Also known as: h, html_escape

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.



273
274
275
# File 'lib/merb-core/controller/mixins/controller.rb', line 273

def escape_xml(obj)
  Erubis::XmlHelper.escape_xml(obj.to_s)
end

#messageObject



132
133
134
# File 'lib/merb-core/controller/mixins/controller.rb', line 132

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

#nginx_send_file(file) ⇒ Object

Uses the nginx specific X-Accel-Redirect header to send a file directly from nginx. For more information, see the nginx wiki: http://wiki.codemongers.com/NginxXSendfile

Parameters

file

Path to file to send to the client.



235
236
237
238
# File 'lib/merb-core/controller/mixins/controller.rb', line 235

def nginx_send_file(file)
  headers['X-Accel-Redirect'] = file
  return ' '
end

#redirect(url, message = nil) ⇒ Object

Parameters

url

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

permanent

When true, return status 301 Moved Permanently

Returns

String

Explanation of redirect.

Examples

redirect("/posts/34") redirect("http://www.merbivore.com/&quot;) redirect("http://www.merbivore.com/&quot;, true)



121
122
123
124
125
126
127
128
129
130
# File 'lib/merb-core/controller/mixins/controller.rb', line 121

def redirect(url, message = nil)
  if message
    notice = Merb::Request.escape([Marshal.dump(message)].pack("m"))
    url = url =~ /\?/ ? "#{url}&_message=#{notice}" : "#{url}?_message=#{notice}"
  end
  self.status = 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 = '

' suffix = "

\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.



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

def render_deferred(&blk)
  must_support_streaming!
  Proc.new {|response|
    result = blk.call
    response.send_status(result.length)
    response.send_header
    response.write(result)
  }
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

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.



98
99
100
101
102
103
104
105
106
# File 'lib/merb-core/controller/mixins/controller.rb', line 98

def render_then_call(str, &blk)
  must_support_streaming!
  Proc.new {|response|
    response.send_status(str.length)
    response.send_header
    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

a chunk of data to return.



64
65
66
67
# File 'lib/merb-core/controller/mixins/controller.rb', line 64

def send_chunk(data)
  @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

Path to file to send to the client.

opts

Options for sending the data (see below).

Options (opts)

:disposition::

The disposition of the file send. Defaults to "attachment".

:filename::

The name to use for the file. Defaults to the filename of file.

:type:: The content type.



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/merb-core/controller/mixins/controller.rb', line 177

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

Path to file to send to the client.

opts

Options for sending the file (see below).

Options (opts)

:disposition::

The disposition of the file send. Defaults to "attachment".

:filename::

The name to use for the file. Defaults to the filename of file.

:type:: The content type.

Returns

IO

An I/O stream for the file.



152
153
154
155
156
157
158
159
160
161
162
# File 'lib/merb-core/controller/mixins/controller.rb', line 152

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'
  )
  File.open(file, 'rb')
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.



250
251
252
253
# File 'lib/merb-core/controller/mixins/controller.rb', line 250

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

#stream_file(opts = {}, &stream) ⇒ Object

Streams a file over HTTP.

Parameters

opts

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

The disposition of the file send. Defaults to "attachment".

:type:: The content type. :content_length:: The length of the content to send. :filename:: 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



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/merb-core/controller/mixins/controller.rb', line 211

def stream_file(opts={}, &stream)
  must_support_streaming!
  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',
    'CONTENT-LENGTH'            => opts[:content_length]
  )
  Proc.new{|response|
    response.send_status(opts[:content_length])
    response.send_header
    stream.call(response)
  }
end