[Mongrel] need help writing a plugin

Jeroen Houben jeroen at supercool.nl
Mon Mar 12 17:29:04 EDT 2007


Zed A. Shaw wrote:
> On Mon, 12 Mar 2007 13:47:27 +0100
> Jeroen Houben <jeroen at supercool.nl> wrote:
> 
>> Hi,
>>
>> I'm halfway developing a tiny plugin that allows people to scrub flash 
>> video files. I've got my plugin setup to monitor a directory /movies.
>> Whenever a .flv file is requested within that directory, some stuff 
>> should happen, if not, the request should be processed as usual. I don't 
>> know how to do the latter..
> 
> Handlers are put in a chain and you can load them in front or back
> (default is in back).  In your case, you want your handler to either do
> the processing and then set the response to finished (see HttpResponse
> docs), or simply ignore the request and let it continue.  Then, you'll
> just register the handler on "/" but give the :in_front => true option.
> 
> Let me know if you need more than that.
> 

Hi Zed, thanks for your reply.

Okay I understand the theory, but how do I continue? I thought simply 
returning from my process() method would do the trick, but the code 
below doesn't work, it gives a 404 for files that do exists, but are not 
flv. I just want any file that is not .flv to be served normally.

   def process(request, response)

     # only stream flv files
     if File.extname(request.params['REQUEST_PATH']).downcase == '.flv'
       puts "not a flv, so returning to the next handler on the stack"
       return
     end


Here's my config:

uri "/movies",
   :handler => plugin("/handlers/streamert"),
   :in_front => true


I'll post the whole init.rb below, just in case.

require 'mongrel'
require 'gem_plugin'

class Streamert < GemPlugin::Plugin "/handlers"
   include Mongrel::HttpHandlerPlugin

   def initialize(options = {})
     @docroot = options[:cwd] + "/" + options[:docroot]
   end

   def process(request, response)

     # only stream flv files
     if File.extname(request.params['REQUEST_PATH']).downcase == '.flv'
       puts "not a flv, so returning to the next handler on the stack"
       return
     end

     filename = @docroot + request.params['REQUEST_PATH']

     # check if file exists
     unless File.exists?(filename) && File.readable?(filename)
       response.start(404, true) do |head,out|
         out.write "Could not open file #{request.params['REQUEST_PATH']}\n"
       end
     end

     # see if an offset was given
     offset = 
Mongrel::HttpRequest.query_parse(request.params['QUERY_STRING'])['offset'].to_i
     # check for sane offset
     offset = 0 unless (0...File.size(filename)).include? offset

     begin
       response.start(200, true) do |head,out|

         head['Content-Type'] = 'video/x-flv'

         # write flv marker bytes to response stream
         if pos != 0
           out.write "FLV"
           out.write [1].pack("C")
           out.write [1].pack("C")
           out.write [9].pack("N")
           out.write [9].pack("N")
         end

         # read and output flv file optionally starting at a given offset
         File.open(filename, "rb") do |f|
           f.seek(offset)
           while (!f.eof) do
             out.write f.read(8092)
           end
         end
       end
     rescue Exception => e
       response.start(500, true) do |head,out|
         out.write "error proceessing #{request.params['REQUEST_PATH']}\n"
       end
     end

   end

end


More information about the Mongrel-users mailing list