<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>actionpack/lib/action_controller/failsafe.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -46,10 +46,9 @@ module ActionController
   autoload :Base, 'action_controller/base'
   autoload :Benchmarking, 'action_controller/benchmarking'
   autoload :Caching, 'action_controller/caching'
-  autoload :CgiRequest, 'action_controller/cgi_process'
-  autoload :CgiResponse, 'action_controller/cgi_process'
   autoload :Cookies, 'action_controller/cookies'
   autoload :Dispatcher, 'action_controller/dispatcher'
+  autoload :Failsafe, 'action_controller/failsafe'
   autoload :Filters, 'action_controller/filters'
   autoload :Flash, 'action_controller/flash'
   autoload :Helpers, 'action_controller/helpers'
@@ -89,6 +88,11 @@ module ActionController
   module Http
     autoload :Headers, 'action_controller/headers'
   end
+
+  # DEPRECATE: Remove CGI support
+  autoload :CgiRequest, 'action_controller/cgi_process'
+  autoload :CgiResponse, 'action_controller/cgi_process'
+  autoload :CGIHandler, 'action_controller/cgi_process'
 end
 
 class CGI</diff>
      <filename>actionpack/lib/action_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,184 +1,72 @@
 require 'action_controller/cgi_ext'
 
 module ActionController #:nodoc:
-  class Base
-    # Process a request extracted from a CGI object and return a response. Pass false as &lt;tt&gt;session_options&lt;/tt&gt; to disable
-    # sessions (large performance increase if sessions are not needed). The &lt;tt&gt;session_options&lt;/tt&gt; are the same as for CGI::Session:
-    #
-    # * &lt;tt&gt;:database_manager&lt;/tt&gt; - standard options are CGI::Session::FileStore, CGI::Session::MemoryStore, and CGI::Session::PStore
-    #   (default). Additionally, there is CGI::Session::DRbStore and CGI::Session::ActiveRecordStore. Read more about these in
-    #   lib/action_controller/session.
-    # * &lt;tt&gt;:session_key&lt;/tt&gt; - the parameter name used for the session id. Defaults to '_session_id'.
-    # * &lt;tt&gt;:session_id&lt;/tt&gt; - the session id to use.  If not provided, then it is retrieved from the +session_key+ cookie, or 
-    #   automatically generated for a new session.
-    # * &lt;tt&gt;:new_session&lt;/tt&gt; - if true, force creation of a new session.  If not set, a new session is only created if none currently
-    #   exists.  If false, a new session is never created, and if none currently exists and the +session_id+ option is not set,
-    #   an ArgumentError is raised.
-    # * &lt;tt&gt;:session_expires&lt;/tt&gt; - the time the current session expires, as a Time object.  If not set, the session will continue
-    #   indefinitely.
-    # * &lt;tt&gt;:session_domain&lt;/tt&gt; - the hostname domain for which this session is valid. If not set, defaults to the hostname of the
-    #   server.
-    # * &lt;tt&gt;:session_secure&lt;/tt&gt; - if +true+, this session will only work over HTTPS.
-    # * &lt;tt&gt;:session_path&lt;/tt&gt; - the path for which this session applies.  Defaults to the directory of the CGI script.
-    # * &lt;tt&gt;:cookie_only&lt;/tt&gt; - if +true+ (the default), session IDs will only be accepted from cookies and not from
-    #   the query string or POST parameters. This protects against session fixation attacks.
-    def self.process_cgi(cgi = CGI.new, session_options = {})
-      new.process_cgi(cgi, session_options)
-    end
-
-    def process_cgi(cgi, session_options = {}) #:nodoc:
-      process(CgiRequest.new(cgi, session_options), CgiResponse.new(cgi)).out
-    end
-  end
-
-  class CgiRequest &lt; AbstractRequest #:nodoc:
-    attr_accessor :cgi, :session_options
-    class SessionFixationAttempt &lt; StandardError #:nodoc:
-    end
-
-    DEFAULT_SESSION_OPTIONS = {
-      :database_manager =&gt; CGI::Session::CookieStore, # store data in cookie
-      :prefix           =&gt; &quot;ruby_sess.&quot;,    # prefix session file names
-      :session_path     =&gt; &quot;/&quot;,             # available to all paths in app
-      :session_key      =&gt; &quot;_session_id&quot;,
-      :cookie_only      =&gt; true,
-      :session_http_only=&gt; true
-    }
-
-    def initialize(cgi, session_options = {})
-      @cgi = cgi
-      @session_options = session_options
-      @env = @cgi.__send__(:env_table)
-      super()
-    end
-
-    def query_string
-      qs = @cgi.query_string if @cgi.respond_to?(:query_string)
-      if !qs.blank?
-        qs
-      else
-        super
-      end
-    end
-
-    def body_stream #:nodoc:
-      @cgi.stdinput
-    end
-
-    def cookies
-      @cgi.cookies.freeze
-    end
-
-    def session
-      unless defined?(@session)
-        if @session_options == false
-          @session = Hash.new
-        else
-          stale_session_check! do
-            if cookie_only? &amp;&amp; query_parameters[session_options_with_string_keys['session_key']]
-              raise SessionFixationAttempt
-            end
-            case value = session_options_with_string_keys['new_session']
-              when true
-                @session = new_session
-              when false
-                begin
-                  @session = CGI::Session.new(@cgi, session_options_with_string_keys)
-                # CGI::Session raises ArgumentError if 'new_session' == false
-                # and no session cookie or query param is present.
-                rescue ArgumentError
-                  @session = Hash.new
-                end
-              when nil
-                @session = CGI::Session.new(@cgi, session_options_with_string_keys)
-              else
-                raise ArgumentError, &quot;Invalid new_session option: #{value}&quot;
-            end
-            @session['__valid_session']
-          end
+  class CGIHandler
+    module ProperStream
+      def each
+        while line = gets
+          yield line
         end
       end
-      @session
-    end
 
-    def reset_session
-      @session.delete if defined?(@session) &amp;&amp; @session.is_a?(CGI::Session)
-      @session = new_session
-    end
-
-    def method_missing(method_id, *arguments)
-      @cgi.__send__(method_id, *arguments) rescue super
-    end
-
-    private
-      # Delete an old session if it exists then create a new one.
-      def new_session
-        if @session_options == false
-          Hash.new
+      def read(*args)
+        if args.empty?
+          super || &quot;&quot;
         else
-          CGI::Session.new(@cgi, session_options_with_string_keys.merge(&quot;new_session&quot; =&gt; false)).delete rescue nil
-          CGI::Session.new(@cgi, session_options_with_string_keys.merge(&quot;new_session&quot; =&gt; true))
+          super
         end
       end
+    end
 
-      def cookie_only?
-        session_options_with_string_keys['cookie_only']
-      end
+    def self.dispatch_cgi(app, cgi, out = $stdout)
+      env = cgi.__send__(:env_table)
+      env.delete &quot;HTTP_CONTENT_LENGTH&quot;
 
-      def stale_session_check!
-        yield
-      rescue ArgumentError =&gt; argument_error
-        if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
-          begin
-            # Note that the regexp does not allow $1 to end with a ':'
-            $1.constantize
-          rescue LoadError, NameError =&gt; const_error
-            raise ActionController::SessionRestoreError, &lt;&lt;-end_msg
-Session contains objects whose class definition isn\'t available.
-Remember to require the classes for all objects kept in the session.
-(Original exception: #{const_error.message} [#{const_error.class}])
-end_msg
-          end
+      cgi.stdinput.extend ProperStream
 
-          retry
-        else
-          raise
-        end
-      end
+      env[&quot;SCRIPT_NAME&quot;] = &quot;&quot; if env[&quot;SCRIPT_NAME&quot;] == &quot;/&quot;
 
-      def session_options_with_string_keys
-        @session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).stringify_keys
-      end
-  end
+      env.update({
+        &quot;rack.version&quot; =&gt; [0,1],
+        &quot;rack.input&quot; =&gt; cgi.stdinput,
+        &quot;rack.errors&quot; =&gt; $stderr,
+        &quot;rack.multithread&quot; =&gt; false,
+        &quot;rack.multiprocess&quot; =&gt; true,
+        &quot;rack.run_once&quot; =&gt; false,
+        &quot;rack.url_scheme&quot; =&gt; [&quot;yes&quot;, &quot;on&quot;, &quot;1&quot;].include?(env[&quot;HTTPS&quot;]) ? &quot;https&quot; : &quot;http&quot;
+      })
 
-  class CgiResponse &lt; AbstractResponse #:nodoc:
-    def initialize(cgi)
-      @cgi = cgi
-      super()
-    end
-
-    def out(output = $stdout)
-      output.binmode      if output.respond_to?(:binmode)
-      output.sync = false if output.respond_to?(:sync=)
+      env[&quot;QUERY_STRING&quot;] ||= &quot;&quot;
+      env[&quot;HTTP_VERSION&quot;] ||= env[&quot;SERVER_PROTOCOL&quot;]
+      env[&quot;REQUEST_PATH&quot;] ||= &quot;/&quot;
+      env.delete &quot;PATH_INFO&quot; if env[&quot;PATH_INFO&quot;] == &quot;&quot;
 
+      status, headers, body = app.call(env)
       begin
-        output.write(@cgi.header(@headers))
-
-        if @cgi.__send__(:env_table)['REQUEST_METHOD'] == 'HEAD'
-          return
-        elsif @body.respond_to?(:call)
-          # Flush the output now in case the @body Proc uses
-          # #syswrite.
-          output.flush if output.respond_to?(:flush)
-          @body.call(self, output)
-        else
-          output.write(@body)
-        end
-
-        output.flush if output.respond_to?(:flush)
-      rescue Errno::EPIPE, Errno::ECONNRESET
-        # lost connection to parent process, ignore output
+        out.binmode if out.respond_to?(:binmode)
+        out.sync = false if out.respond_to?(:sync=)
+
+        headers['Status'] = status.to_s
+        out.write(cgi.header(headers))
+
+        body.each { |part|
+          out.write part
+          out.flush if out.respond_to?(:flush)
+        }
+      ensure
+        body.close if body.respond_to?(:close)
       end
     end
   end
+
+  class CgiRequest #:nodoc:
+    DEFAULT_SESSION_OPTIONS = {
+      :database_manager  =&gt; CGI::Session::CookieStore,
+      :prefix            =&gt; &quot;ruby_sess.&quot;,
+      :session_path      =&gt; &quot;/&quot;,
+      :session_key       =&gt; &quot;_session_id&quot;,
+      :cookie_only       =&gt; true,
+      :session_http_only =&gt; true
+    }
+  end
 end</diff>
      <filename>actionpack/lib/action_controller/cgi_process.rb</filename>
    </modified>
    <modified>
      <diff>@@ -24,8 +24,7 @@ module ActionController
         end
       end
 
-      # Backward-compatible class method takes CGI-specific args. Deprecated
-      # in favor of Dispatcher.new(output, request, response).dispatch.
+      # DEPRECATE: Remove CGI support
       def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout)
         new(output).dispatch_cgi(cgi, session_options)
       end
@@ -43,57 +42,16 @@ module ActionController
         callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier =&gt; identifier)
         @prepare_dispatch_callbacks.replace_or_append!(callback)
       end
-
-      # If the block raises, send status code as a last-ditch response.
-      def failsafe_response(fallback_output, status, originating_exception = nil)
-        yield
-      rescue Exception =&gt; exception
-        begin
-          log_failsafe_exception(status, originating_exception || exception)
-          body = failsafe_response_body(status)
-          fallback_output.write &quot;Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}&quot;
-          nil
-        rescue Exception =&gt; failsafe_error # Logger or IO errors
-          $stderr.puts &quot;Error during failsafe response: #{failsafe_error}&quot;
-          $stderr.puts &quot;(originally #{originating_exception})&quot; if originating_exception
-        end
-      end
-
-      private
-        def failsafe_response_body(status)
-          error_path = &quot;#{error_file_path}/#{status.to_s[0..2]}.html&quot;
-
-          if File.exist?(error_path)
-            File.read(error_path)
-          else
-            &quot;&lt;html&gt;&lt;body&gt;&lt;h1&gt;#{status}&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;&quot;
-          end
-        end
-
-        def log_failsafe_exception(status, exception)
-          message = &quot;/!\\ FAILSAFE /!\\  #{Time.now}\n  Status: #{status}\n&quot;
-          message &lt;&lt; &quot;  #{exception}\n    #{exception.backtrace.join(&quot;\n    &quot;)}&quot; if exception
-          failsafe_logger.fatal message
-        end
-
-        def failsafe_logger
-          if defined?(::RAILS_DEFAULT_LOGGER) &amp;&amp; !::RAILS_DEFAULT_LOGGER.nil?
-            ::RAILS_DEFAULT_LOGGER
-          else
-            Logger.new($stderr)
-          end
-        end
     end
 
     cattr_accessor :middleware
     self.middleware = MiddlewareStack.new
-
-    cattr_accessor :error_file_path
-    self.error_file_path = Rails.public_path if defined?(Rails.public_path)
+    self.middleware.use &quot;ActionController::Failsafe&quot;
 
     include ActiveSupport::Callbacks
     define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
 
+    # DEPRECATE: Remove arguments
     def initialize(output = $stdout, request = nil, response = nil)
       @output, @request, @response = output, request, response
       @app = @@middleware.build(lambda { |env| self.dup._call(env) })
@@ -120,14 +78,9 @@ module ActionController
       end
     end
 
+    # DEPRECATE: Remove CGI support
     def dispatch_cgi(cgi, session_options)
-      if cgi ||= self.class.failsafe_response(@output, '400 Bad Request') { CGI.new }
-        @request = CgiRequest.new(cgi, session_options)
-        @response = CgiResponse.new(cgi)
-        dispatch
-      end
-    rescue Exception =&gt; exception
-      failsafe_rescue exception
+      CGIHandler.dispatch_cgi(self, cgi, @output)
     end
 
     def call(env)
@@ -160,40 +113,22 @@ module ActionController
       Base.logger.flush
     end
 
-    def mark_as_test_request!
-      @test_request = true
-      self
-    end
-
-    def test_request?
-      @test_request
-    end
-
     def checkin_connections
       # Don't return connection (and peform implicit rollback) if this request is a part of integration test
-      return if test_request?
+      # TODO: This callback should have direct access to env
+      return if @request.key?(&quot;action_controller.test&quot;)
       ActiveRecord::Base.clear_active_connections!
     end
 
     protected
       def handle_request
         @controller = Routing::Routes.recognize(@request)
-        @controller.process(@request, @response).out(@output)
+        @controller.process(@request, @response).out
       end
 
       def failsafe_rescue(exception)
-        if @test_request
-          process_with_exception(exception)
-        else
-          self.class.failsafe_response(@output, '500 Internal Server Error', exception) do
-            process_with_exception(exception)
-          end
-        end
-      end
-
-      def process_with_exception(exception)
         if @controller ||= (::ApplicationController rescue Base)
-          @controller.process_with_exception(@request, @response, exception).out(@output)
+          @controller.process_with_exception(@request, @response, exception).out
         else
           raise exception
         end</diff>
      <filename>actionpack/lib/action_controller/dispatcher.rb</filename>
    </modified>
    <modified>
      <diff>@@ -257,7 +257,8 @@ module ActionController
             &quot;CONTENT_LENGTH&quot; =&gt; data ? data.length.to_s : nil,
             &quot;HTTP_COOKIE&quot;    =&gt; encode_cookies,
             &quot;HTTPS&quot;          =&gt; https? ? &quot;on&quot; : &quot;off&quot;,
-            &quot;HTTP_ACCEPT&quot;    =&gt; accept
+            &quot;HTTP_ACCEPT&quot;    =&gt; accept,
+            &quot;action_controller.test&quot; =&gt; true
           )
 
           (headers || {}).each do |key, value|
@@ -273,7 +274,7 @@ module ActionController
           ActionController::Base.clear_last_instantiation!
 
           env['rack.input'] = data.is_a?(IO) ? data : StringIO.new(data || '')
-          @status, @headers, result_body = ActionController::Dispatcher.new.mark_as_test_request!.call(env)
+          @status, @headers, result_body = ActionController::Dispatcher.new.call(env)
           @request_count += 1
 
           @controller = ActionController::Base.last_instantiation</diff>
      <filename>actionpack/lib/action_controller/integration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -164,7 +164,7 @@ end_msg
       @status || super
     end
 
-    def out(output = $stdout, &amp;block)
+    def out(&amp;block)
       # Nasty hack because CGI sessions are closed after the normal
       # prepare! statement
       set_cookies!</diff>
      <filename>actionpack/lib/action_controller/rack_process.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,6 @@ class DispatcherTest &lt; Test::Unit::TestCase
   Dispatcher = ActionController::Dispatcher
 
   def setup
-    @output = StringIO.new
     ENV['REQUEST_METHOD'] = 'GET'
 
     # Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
@@ -16,7 +15,7 @@ class DispatcherTest &lt; Test::Unit::TestCase
 
     Dispatcher.stubs(:require_dependency)
 
-    @dispatcher = Dispatcher.new(@output)
+    @dispatcher = Dispatcher.new
   end
 
   def teardown
@@ -25,17 +24,17 @@ class DispatcherTest &lt; Test::Unit::TestCase
 
   def test_clears_dependencies_after_dispatch_if_in_loading_mode
     ActiveSupport::Dependencies.expects(:clear).once
-    dispatch(@output, false)
+    dispatch(false)
   end
 
   def test_reloads_routes_before_dispatch_if_in_loading_mode
     ActionController::Routing::Routes.expects(:reload).once
-    dispatch(@output, false)
+    dispatch(false)
   end
 
   def test_clears_asset_tag_cache_before_dispatch_if_in_loading_mode
     ActionView::Helpers::AssetTagHelper::AssetTag::Cache.expects(:clear).once
-    dispatch(@output, false)
+    dispatch(false)
   end
 
   def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode
@@ -51,12 +50,16 @@ class DispatcherTest &lt; Test::Unit::TestCase
   end
 
   def test_failsafe_response
-    CGI.expects(:new).raises('some multipart parsing failure')
-    Dispatcher.expects(:log_failsafe_exception)
-
-    assert_nothing_raised { dispatch }
-
-    assert_equal &quot;Status: 400 Bad Request\r\nContent-Type: text/html\r\n\r\n&lt;html&gt;&lt;body&gt;&lt;h1&gt;400 Bad Request&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;&quot;, @output.string
+    Dispatcher.any_instance.expects(:dispatch_unlocked).raises('b00m')
+    ActionController::Failsafe.any_instance.expects(:log_failsafe_exception)
+
+    assert_nothing_raised do
+      assert_equal [
+        500,
+        {&quot;Content-Type&quot; =&gt; &quot;text/html&quot;},
+        &quot;&lt;html&gt;&lt;body&gt;&lt;h1&gt;500 Internal Server Error&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;&quot;
+      ], dispatch
+    end
   end
 
   def test_prepare_callbacks
@@ -77,7 +80,7 @@ class DispatcherTest &lt; Test::Unit::TestCase
 
     # Make sure they are only run once
     a = b = c = nil
-    @dispatcher.send :dispatch
+    dispatch
     assert_nil a || b || c
   end
 
@@ -92,15 +95,10 @@ class DispatcherTest &lt; Test::Unit::TestCase
   end
 
   private
-    def dispatch(output = @output, cache_classes = true)
-      controller = mock
-      controller.stubs(:process).returns(controller)
-      controller.stubs(:out).with(output).returns('response')
-
-      ActionController::Routing::Routes.stubs(:recognize).returns(controller)
-
+    def dispatch(cache_classes = true)
+      Dispatcher.any_instance.stubs(:handle_request).returns([200, {}, 'response'])
       Dispatcher.define_dispatcher_callbacks(cache_classes)
-      Dispatcher.dispatch(nil, {}, output)
+      @dispatcher.call({})
     end
 
     def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)</diff>
      <filename>actionpack/test/controller/dispatcher_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -230,14 +230,13 @@ class RackResponseTest &lt; BaseRackTest
   def setup
     super
     @response = ActionController::RackResponse.new(@request)
-    @output = StringIO.new('')
   end
 
   def test_simple_output
     @response.body = &quot;Hello, World!&quot;
     @response.prepare!
 
-    status, headers, body = @response.out(@output)
+    status, headers, body = @response.out
     assert_equal &quot;200 OK&quot;, status
     assert_equal({
       &quot;Content-Type&quot; =&gt; &quot;text/html; charset=utf-8&quot;,
@@ -258,7 +257,7 @@ class RackResponseTest &lt; BaseRackTest
     end
     @response.prepare!
 
-    status, headers, body = @response.out(@output)
+    status, headers, body = @response.out
     assert_equal &quot;200 OK&quot;, status
     assert_equal({&quot;Content-Type&quot; =&gt; &quot;text/html; charset=utf-8&quot;, &quot;Cache-Control&quot; =&gt; &quot;no-cache&quot;, &quot;Set-Cookie&quot; =&gt; []}, headers)
 
@@ -274,7 +273,7 @@ class RackResponseTest &lt; BaseRackTest
     @response.body = &quot;Hello, World!&quot;
     @response.prepare!
 
-    status, headers, body = @response.out(@output)
+    status, headers, body = @response.out
     assert_equal &quot;200 OK&quot;, status
     assert_equal({
       &quot;Content-Type&quot; =&gt; &quot;text/html; charset=utf-8&quot;,
@@ -294,7 +293,6 @@ class RackResponseHeadersTest &lt; BaseRackTest
   def setup
     super
     @response = ActionController::RackResponse.new(@request)
-    @output = StringIO.new('')
     @response.headers['Status'] = &quot;200 OK&quot;
   end
 
@@ -317,6 +315,6 @@ class RackResponseHeadersTest &lt; BaseRackTest
   private
     def response_headers
       @response.prepare!
-      @response.out(@output)[1]
+      @response.out[1]
     end
 end</diff>
      <filename>actionpack/test/controller/rack_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -637,7 +637,7 @@ class UrlEncodedRequestParameterParsingTest &lt; ActiveSupport::TestCase
     input = {
       &quot;customers[boston][first][name]&quot; =&gt; [ &quot;David&quot; ],
       &quot;something_else&quot; =&gt; [ &quot;blah&quot; ],
-      &quot;logo&quot; =&gt; [ File.new(File.dirname(__FILE__) + &quot;/cgi_test.rb&quot;).path ]
+      &quot;logo&quot; =&gt; [ File.new(File.dirname(__FILE__) + &quot;/rack_test.rb&quot;).path ]
     }
 
     expected_output = {
@@ -649,7 +649,7 @@ class UrlEncodedRequestParameterParsingTest &lt; ActiveSupport::TestCase
         }
       },
       &quot;something_else&quot; =&gt; &quot;blah&quot;,
-      &quot;logo&quot; =&gt; File.new(File.dirname(__FILE__) + &quot;/cgi_test.rb&quot;).path,
+      &quot;logo&quot; =&gt; File.new(File.dirname(__FILE__) + &quot;/rack_test.rb&quot;).path,
     }
 
     assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)</diff>
      <filename>actionpack/test/controller/request_test.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>actionpack/test/controller/cgi_test.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>27ebfd795ff106efae8cbe318d7b15b1a3c63b13</id>
    </parent>
  </parents>
  <author>
    <name>Joshua Peek</name>
    <login>josh</login>
    <email>josh@joshpeek.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/9c9da6c892d715ca22c3cf51f50deb1d80029c66</url>
  <id>9c9da6c892d715ca22c3cf51f50deb1d80029c66</id>
  <committed-date>2008-12-04T18:39:36-08:00</committed-date>
  <authored-date>2008-12-04T18:39:36-08:00</authored-date>
  <message>Boot out CGI Processor.

* Add ActionController::CGIHandler as a backwards compatible CGI wrapper around Rack.
* Also pull failsafe responder into ActionController::Failsafe middleware.</message>
  <tree>1605da4f53bb22b5f793c0d78161e46fdb8603bf</tree>
  <committer>
    <name>Joshua Peek</name>
    <login>josh</login>
    <email>josh@joshpeek.com</email>
  </committer>
</commit>
