# Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
While requesting resource #{env['PATH_INFO'].to_html}, a fatal error occurred.
" body.puts "#{ex.class.name.to_html}: #{ex.to_s.to_html}" body.puts "
There is nothing more we can do to fix the problem at this point.
" body.puts "We apologize for the inconvenience.
" body.puts "" body.rewind return [400, {"Content-Type" => "text/html"}, body] end def redirect(env, ex) return @app.call(env.merge('PATH_INFO' => @location, 'REQUEST_METHOD' => 'GET')) end def call(env) begin return @app.call(env) rescue Exception => ex if env['PATH_INFO'] == @location return fatal_error(env, ex) else # If redirection fails begin return redirect(env, ex) rescue return fatal_error(env, ex) end end end end end # Legacy Support ExceptionRedirector = ExceptionHandler class Redirector private def normalize_keys(redirects) redirects.each do |key, value| result = nil case value when String result = @strings when Regexp result = @patterns else $stderr.puts "Warning, could not process redirect #{key.inspect} to #{value.inspect}!" next end if key.kind_of? Array key.each do |subkey| result[subkey] = value end else result[key] = value end end end public def initialize(app, options = {}) @app = app @strings = {} @patterns = {} normalize_keys(options[:redirects]) if options[:redirects] @errors = options[:errors] LOG.info "#{self.class.name}: Running with #{@strings.size + @patterns.size} rules" end def redirect(uri, match_data) if uri.respond_to? :call return uri.call(match_data) else return [301, {"Location" => uri.to_s}, []] end end def call(env) base_path = env['PATH_INFO'] if uri = @strings[base_path] return redirect(@strings[base_path], base_path) end @patterns.each do |pattern, uri| if match_data = base_path.match(pattern) return redirect(uri, match_data) end end response = @app.call(env) if @errors && response[0] >= 400 && uri = @errors[response[0]] error_request = env.merge("PATH_INFO" => uri, "REQUEST_METHOD" => "GET") error_response = @app.call(error_request) if error_response[0] >= 400 raise FailedRequestError.new(env['PATH_INFO'], response[0], uri, error_response[0]) else # Feed the error code back with the error document error_response[0] = response[0] return error_response end else return response end end end end end