module Speedup class Middleware def initialize(app) @app = app @redirects = [] end def call(env) return @app.call(env) if !Speedup.enabled? Speedup.setup_request(env['action_dispatch.request_id']) status, headers, body = @app.call(env) Speedup.request.save if Speedup.show_bar? && headers['Content-Type'] =~ /text\/html/ case status.to_i when 200..299, 400..500 body = SpeedupBody.new(body, @redirects) # headers['Content-Length'] = body.collect{|row| row.length}.sum.to_s @redirects = [] when 300..400 @redirects.push(Speedup.request.id) end end [status, headers, body] rescue Exception => exception Speedup.request && Speedup.request.save raise exception end class SpeedupBody include Enumerable def initialize(rack_body, redirects=[]) @rack_body = rack_body @redirects = redirects end def each(*params, &block) @rack_body.each do |response_row| if response_row =~ /<\/body>/ yield response_row.sub(/<\/body>/, bar_html+'') else yield response_row end end end def body @rack_body.body.sub(/<\/body>/, bar_html+'') end def close @rack_body.close if @rack_body && @rack_body.respond_to?(:close) end def respond_to?(method, include_private = false) if method.to_s == 'to_path' @rack_body.respond_to?(method) else super end end def to_path @rack_body.to_path end def to_a @rack_body.to_ary end def to_ary to_a end def bar_html str = "#{styles}" + '
' + "' str end private def styles <<-END_STYLES END_STYLES end def javascript result = <<-'END_JS' function loadRequestData(url) { speedup_rails_ajax( url , function(xhr) { res = stripScript( xhr.responseText ); appendHtml(document.getElementById('speedup_rails_bar'), res[0]); executeScript(res[1]); }); } function appendHtml(el, str) { var div = document.createElement('div'); div.innerHTML = str; while (div.children.length > 0) { el.appendChild(div.children[0]); } } function stripScript(text) { var scripts = ''; var cleaned = text.replace(/]*>([\s\S]*?)<\/script>/gi, function(){ scripts += arguments[1] + '\n'; return ''; }); return [cleaned, scripts]; }; function executeScript(scripts) { if (window.execScript){ window.execScript(scripts); } else { var head = document.getElementsByTagName('head')[0]; var scriptElement = document.createElement('script'); scriptElement.setAttribute('type', 'text/javascript'); scriptElement.innerHTML = scripts; head.appendChild(scriptElement); head.removeChild(scriptElement); } } function speedup_rails_ajax(url, callback) { var xmlhttp; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 ) { callback(xmlhttp); } } xmlhttp.open("GET", url, true); xmlhttp.send(); } END_JS result.html_safe end end end end