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: wiki.codemongers.com/NginxXSendfile

Parameters

file<String>

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

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

permanent<Boolean>

When true, return status 301 Moved Permanently

Returns

String

Explanation of redirect.

Examples

redirect("/posts/34")
redirect("http://www.merbivore.com/")
redirect("http://www.merbivore.com/", 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 = '<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.



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



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

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



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



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.

expires<~gmtime:~strftime, Hash>

An expiration time for the cookie, or a hash of cookie options.




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


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