Index: lib/mouseHole/proxyhandler.rb =================================================================== --- lib/mouseHole/proxyhandler.rb (revision 107) +++ lib/mouseHole/proxyhandler.rb (working copy) @@ -5,6 +5,7 @@ class MountHandler < Mongrel::HttpHandler include HandlerMixin include LoggerMixin + include Views def initialize(block) @block = block @@ -30,52 +31,66 @@ end def process(request, response) - start = Time.now - uri, reqh, env = page_prep(request) - - if uri.path =~ %r!/([\w\-]{32})/! - token, trail = $1, $' - app = @central.find_app :token => token - if app - hdlr = app.find_handler :is => :mount, :on => :all, :name => trail - return hdlr.process(request, response) + begin + start = Time.now + uri, reqh, env = page_prep(request) + + if uri.path =~ %r!/([\w\-]{32})/! + token, trail = $1, $' + app = @central.find_app :token => token + if app + hdlr = app.find_handler :is => :mount, :on => :all, :name => trail + return hdlr.process(request, response) + end end - end - header = [] - choose_header(reqh, header) - set_via(header) - - http = Net::HTTP.new(env['server-name'], env['server-port'], @central.proxy_host, @central.proxy_port) - http.open_timeout = 10 - http.read_timeout = 20 - reqm = Net::HTTP.const_get(env['request-method'].capitalize) - debug "-> connecting to #{uri}", :since => start - resin = http.request(reqm.new(uri.request_uri, header), reqm::REQUEST_HAS_BODY ? request.body : nil) do |resin| header = [] - debug " > opened #{uri}", :since => start - choose_header(resin.to_hash, header) + choose_header(reqh, header) set_via(header) - page = Page.new(uri, resin.code, header) - if page.converter and !DOMAINS.include?(env['server-name']) and @central.rewrite(page, resin) - info "*> rewriting #{page.location}", :since => start - output(page, response) - else - debug " > streaming #{page.location}", :since => start - response.status = resin.code.to_i - header.each { |k, v| response.header[k] = v } - response.send_plain_status - response.send_header - resin.read_body do |chunk| - response.write(chunk) + http = Net::HTTP.new(env['server-name'], env['server-port'], @central.proxy_host, @central.proxy_port) + http.open_timeout = 10 + http.read_timeout = 20 + reqm = Net::HTTP.const_get(env['request-method'].capitalize) + debug "-> connecting to #{uri}", :since => start + resin = http.request(reqm.new(uri.request_uri, header), reqm::REQUEST_HAS_BODY ? request.body : nil) do |resin| + header = [] + debug " > opened #{uri}", :since => start + choose_header(resin.to_hash, header) + set_via(header) + + page = Page.new(uri, resin.code, header) + if page.converter and !DOMAINS.include?(env['server-name']) and @central.rewrite(page, resin) + info "*> rewriting #{page.location}", :since => start + output(page, response) + else + debug " > streaming #{page.location}", :since => start + response.status = resin.code.to_i + header.each { |k, v| response.header[k] = v } + response.send_plain_status + response.send_header + resin.read_body do |chunk| + response.write(chunk) + end end end + debug "-> finished #{uri}", :since => start + rescue + handle_error($!, response) end - debug "-> finished #{uri}", :since => start resin end - end + def handle_error(error, response) + response.status = 500 + response.send_plain_status + response.header['Content-Type'] = 'text/html; charset=utf-8' + response.send_header + error 'ERROR: ' + $!.class.name + ' ' + $!.message + @error = error + render response, :error + end + end + end Index: lib/mouseHole/views.rb =================================================================== --- lib/mouseHole/views.rb (revision 107) +++ lib/mouseHole/views.rb (working copy) @@ -13,7 +13,7 @@ script :type => "text/javascript", :src => R(Static, 'js', 'jquery.js') script :type => "text/javascript", :src => R(Static, 'js', 'interface.js') script :type => "text/javascript", :src => R(Static, 'js', 'mouseHole.js') - style "@import '#{R(Static, 'css', 'doorway.css')}';", :type => 'text/css' + style "@import '#{self/R(Static, 'css', 'doorway.css')}';", :type => 'text/css' end body do div.mousehole! do @@ -220,11 +220,47 @@ def data div.main do - h1 { 'Data ' + span('Viewer') } + h1 { text('Data '); span('Viewer') } p %{Welcome to MouseHole.} end end + def error + div.main do + div.exception do + case @error + when Errno::ECONNREFUSED + h2 "Connection Refused" + p "The remote server refused the connection. Check that you got the + URL right, and make sure the remote service is running." + when Errno::EINVAL + h2 "Invalid" + p "Connecting to the remote host failed, probably due to an +invalid IP address" + when SocketError + h2 "#{@error.message.gsub(/\n/, '
')}" + if @error.message =~ /Hostname not known/ + p "The remote host could not be found. You might want to try +with or without a 'www.', check its spelling, or recite the incantation +backward." + end + else + h2 "#{@error.class}" + h3(@error.message.gsub(/\n/, '
')) + p "The exception was:" + ul.backtrace do + @error.backtrace.each do |bt| + li "from #{bt}" + end + end + end + p.actionbuttons do + button(:class => 'action', :onclick => "window.location.reload()") { "Try again" } + end + end + end + end + def red str RedCloth.new(str.gsub(/^ +/, '')).to_html end Index: lib/mouseHole/mixins/handler.rb =================================================================== --- lib/mouseHole/mixins/handler.rb (revision 107) +++ lib/mouseHole/mixins/handler.rb (working copy) @@ -77,6 +77,20 @@ return URI(uri), reqh, env end + def render(response, *args, &block) + begin + debug '-> render' + @root = 'http://mh' + m = Mab.new({}, self) + s=m.capture{send(:doorway,*args,&block)} + s=m.capture{send(:layout){s}} if /^_/!~args[0].to_s and m.respond_to?:layout + response.write(s) + rescue Exception + error $! + error $!.backtrace.join("\n") + end + end + end end Index: static/css/doorway.css =================================================================== --- static/css/doorway.css (revision 107) +++ static/css/doorway.css (working copy) @@ -367,3 +367,7 @@ list-style: none; margin: 0; } + +#mousehole p.actionbuttons { + text-align: center; +}