This file is indexed.

/usr/lib/ruby/vendor_ruby/merb-core/controller/mixins/controller.rb is in ruby-merb-core 1.1.3+dfsg-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
module Merb
  # Module that is mixed in to all implemented controllers.
  module ControllerMixin
    
    # 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
    def run_later(&blk)
      Merb.run_later(&blk)
    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
    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
    
    # 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
    def send_chunk(data)
      only_runs_on_mongrel!
      @response.write('%x' % data.size + "\r\n")
      @response.write(data + "\r\n")
    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
    def render_deferred(&blk)
      Proc.new do |response|
        response.write(blk.call)
      end
    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
    def render_then_call(str, &blk)
      Proc.new do |response|
        response.write(str)
        blk.call
      end
    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
    # :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.
    # 
    # ==== 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!')
    # 
    # :api: public
    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
    
    # Retreives the redirect message either locally or from the request.
    # 
    # :api: public
    def message
      @_message = defined?(@_message) ? @_message : request.message
    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
    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
    
    # 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
    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
    
    # 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
    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
    
    # 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:
    # http://wiki.codemongers.com/NginxXSendfile
    # 
    # and the following sample gist:
    # http://gist.github.com/11225
    # 
    # there's also example application up on GitHub:
    # 
    # http://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
    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  
    
    # 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
    def set_cookie(name, value, expires)
      options = expires.is_a?(Hash) ? expires : {:expires => expires}
      cookies.set_cookie(name, value, options)
    end
    
    # 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
    def delete_cookie(name)
      set_cookie(name, nil, Merb::Const::COOKIE_EXPIRED_TIME)
    end
    
    # 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
    def escape_xml(obj)
      Merb::Parse.escape_xml(obj.to_s)
    end
    alias h escape_xml
    alias escape_html escape_xml
    
    private
    
    # Marks an output method that only runs on the Mongrel webserver.
    # 
    # ==== Raises
    # NotImplemented:: The Rack adapter is not mongrel.
    # 
    # :api: private
    def only_runs_on_mongrel!
      unless Merb::Config[:log_stream] == 'mongrel'
        raise(Merb::ControllerExceptions::NotImplemented, "Current Rack adapter is not mongrel. cannot support this feature")
      end
    end

    # Process a redirect url with options, appending messages onto the url as query params
    # 
    # ==== Parameter
    # url<String>:: the url being redirected to
    # 
    # ==== Options (opts)
    # :message<Hash>::
    #   A hash of key/value strings to be passed along within the redirect query params.
    # :notice<String>::
    #   A shortcut to passing :message => {:notice => "..."}
    # :error<String>::
    #   A shortcut to passing :message => {:error => "..."}
    # :success<String>::
    #   A shortcut to passing :message => {:success => "..."}
    # 
    # ==== Returns
    # String:: the new url with messages attached
    #     
    # :api: private
    def handle_redirect_messages(url, opts={})
      opts = opts.dup

      # check opts for message shortcut keys (and assign them to message)
      [:notice, :error, :success].each do |message_key|
        if opts[message_key]
          opts[:message] ||= {}
          opts[:message][message_key] = opts[message_key]
        end
      end
      
      # append message query param if message is passed
      if opts[:message]
        notice = Merb::Parse.escape([Marshal.dump(opts[:message])].pack("m"))
        u = ::URI.parse(url)
        u.query = u.query ? "#{u.query}&_message=#{notice}" : "_message=#{notice}"
        url = u.to_s
      end
      
      url
    end
  end
end