require 'gem_plugin' require 'mongrel' class DownloadProgress < GemPlugin::Plugin "/handlers" include Mongrel::HttpHandlerPlugin def process(request, response) query = Mongrel::HttpRequest.query_parse(request.params['QUERY_STRING']) STDERR.puts "Sending file" send_file(response, File.expand_path("." + query['path']), query) end private # Sends the contents of a file back to the user. def send_file(response, path, query) file_status = File.stat(path) response.status = 200 # Set the last modified times as well and etag for all files response.header[Mongrel::Const::LAST_MODIFIED] = file_status.mtime.httpdate # Calculated the same as apache, not sure how well the works on win32 response.header[Mongrel::Const::ETAG] = Mongrel::Const::ETAG_FORMAT % [file_status.mtime.to_i, file_status.size, file_status.ino] response.header[Mongrel::Const::CONTENT_TYPE] = query['type'].nil? ? @default_content_type : "#{query['type']}" response.header['Content-Disposition'] = (query['disposition'].nil? ? "Inline" : "#{query['disposition']};") + " filename=\"" + (query['filename'].nil? ? File.basename(path) : query['filename']) + "\"" # send a status with out content length response.send_status(file_status.size) response.send_header size = File.size(path) len = 4096 sent = 0 left = size File.open(path, 'rb') do |file| while buf = file.read(len) response.write(buf) left -= len sent += len STDERR.print "\r"+sprintf("%.#{0}f", (sent.to_f / size.to_f)*100)+" %" end end STDERR.puts "" STDERR.puts "Sent file" send_trigger(query['trigger_host'], query['trigger_port'], query['trigger_path']) if(query['trigger_host'] && query['trigger_path']) end #executes the trigger def send_trigger(host, port, path) for i in 0..2 http = Net::HTTP.new(host,(port.nil? ? 80 : port)) req = Net::HTTP::Get.new(path) response = http.request(req) STDERR.puts response.message break if response.message == 'OK' end end end