From db045dbbf60b53dbe013ef25554fd013baf88134 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 24 Nov 2004 01:04:44 +0000 Subject: Initial git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/lib/action_controller/cgi_process.rb | 124 ++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 actionpack/lib/action_controller/cgi_process.rb (limited to 'actionpack/lib/action_controller/cgi_process.rb') diff --git a/actionpack/lib/action_controller/cgi_process.rb b/actionpack/lib/action_controller/cgi_process.rb new file mode 100644 index 0000000000..e69a0b2f8d --- /dev/null +++ b/actionpack/lib/action_controller/cgi_process.rb @@ -0,0 +1,124 @@ +require 'action_controller/cgi_ext/cgi_ext' +require 'action_controller/support/cookie_performance_fix' +require 'action_controller/session/drb_store' +require 'action_controller/session/active_record_store' + +module ActionController #:nodoc: + class Base + # Process a request extracted from an CGI object and return a response. Pass false as session_options to disable + # sessions (large performance increase if sessions are not needed). The session_options are the same as for CGI::Session: + # + # * :database_manager - 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. + # * :session_key - the parameter name used for the session id. Defaults to '_session_id'. + # * :session_id - the session id to use. If not provided, then it is retrieved from the +session_key+ parameter + # of the request, or automatically generated for a new session. + # * :new_session - 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. + # * :session_expires - the time the current session expires, as a +Time+ object. If not set, the session will continue + # indefinitely. + # * :session_domain - the hostname domain for which this session is valid. If not set, defaults to the hostname of the + # server. + # * :session_secure - if +true+, this session will only work over HTTPS. + # * :session_path - the path for which this session applies. Defaults to the directory of the CGI script. + 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 < AbstractRequest #:nodoc: + attr_accessor :cgi + + DEFAULT_SESSION_OPTIONS = + { "database_manager" => CGI::Session::PStore, "prefix" => "ruby_sess.", "session_path" => "/" } + + def initialize(cgi, session_options = {}) + @cgi = cgi + @session_options = session_options + super() + end + + def query_parameters + @cgi.query_string ? CGIMethods.parse_query_parameters(@cgi.query_string) : {} + end + + def request_parameters + CGIMethods.parse_request_parameters(@cgi.params) + end + + def env + @cgi.send(:env_table) + end + + def cookies + @cgi.cookies.freeze + end + + def host + env["HTTP_X_FORWARDED_HOST"] || @cgi.host.split(":").first + end + + def session + return @session unless @session.nil? + begin + @session = (@session_options == false ? {} : CGI::Session.new(@cgi, DEFAULT_SESSION_OPTIONS.merge(@session_options))) + @session["__valid_session"] + return @session + rescue ArgumentError => e + @session.delete if @session + raise( + ActionController::SessionRestoreError, + "Session contained objects where the class definition wasn't available. " + + "Remember to require classes for all objects kept in the session. " + + "The session has been deleted." + ) + end + end + + def reset_session + @session.delete + @session = (@session_options == false ? {} : new_session) + end + + def method_missing(method_id, *arguments) + @cgi.send(method_id, *arguments) rescue super + end + + private + def new_session + CGI::Session.new(@cgi, DEFAULT_SESSION_OPTIONS.merge(@session_options).merge("new_session" => true)) + end + end + + class CgiResponse < AbstractResponse #:nodoc: + def initialize(cgi) + @cgi = cgi + super() + end + + def out + convert_content_type!(@headers) + $stdout.binmode if $stdout.respond_to?(:binmode) + print @cgi.header(@headers) + if @body.respond_to?(:call) + @body.call(self) + else + print @body + end + end + + private + def convert_content_type!(headers) + if headers["Content-Type"] + headers["type"] = headers["Content-Type"] + headers.delete "Content-Type" + end + end + end +end -- cgit v1.2.3