From 92050f6c6f586b2a73aeb61da4f41b9822bbcf6d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 2 Jun 2008 21:02:26 -0500 Subject: [PATCH] Ensure Rack processor reads CGI output_cookies for the session cookie. --- .../lib/action_controller/dispatcher.rb | 2 +- .../lib/action_controller/rack_process.rb | 10 +++- actionpack/test/controller/rack_test.rb | 56 +++++++++++++++++-- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index b40f1ba9be..7162fb8b1f 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -125,7 +125,7 @@ def dispatch_cgi(cgi, session_options) def call(env) @request = RackRequest.new(env) - @response = RackResponse.new + @response = RackResponse.new(@request) dispatch end diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index 16625519b6..d5fb78c44d 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -4,6 +4,7 @@ module ActionController #:nodoc: class RackRequest < AbstractRequest #:nodoc: attr_accessor :env, :session_options + attr_reader :cgi class SessionFixationAttempt < StandardError #:nodoc: end @@ -199,7 +200,8 @@ def unescape(s) class RackResponse < AbstractResponse #:nodoc: attr_accessor :status - def initialize + def initialize(request) + @request = request @writer = lambda { |x| @body << x } @block = nil super() @@ -270,9 +272,9 @@ def normalize_headers(options = "text/html") else cookies << cookie.to_s end - @output_cookies.each { |c| cookies << c.to_s } if @output_cookies + @request.cgi.output_cookies.each { |c| cookies << c.to_s } if @request.cgi.output_cookies - headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].compact.join("\n") + headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact end options.each { |k,v| headers[k] = v } @@ -283,6 +285,8 @@ def normalize_headers(options = "text/html") end class CGIWrapper < ::CGI + attr_reader :output_cookies + def initialize(request, *args) @request = request @args = *args diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index cd4151783e..026b0195d1 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -3,7 +3,36 @@ class BaseRackTest < Test::Unit::TestCase def setup - @env = {"HTTP_MAX_FORWARDS"=>"10", "SERVER_NAME"=>"glu.ttono.us:8007", "FCGI_ROLE"=>"RESPONDER", "HTTP_X_FORWARDED_HOST"=>"glu.ttono.us", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.5.1 (KHTML, like Gecko) Safari/312.3.1", "PATH_INFO"=>"", "HTTP_ACCEPT_LANGUAGE"=>"en", "HTTP_HOST"=>"glu.ttono.us:8007", "SERVER_PROTOCOL"=>"HTTP/1.1", "REDIRECT_URI"=>"/dispatch.fcgi", "SCRIPT_NAME"=>"/dispatch.fcgi", "SERVER_ADDR"=>"207.7.108.53", "REMOTE_ADDR"=>"207.7.108.53", "SERVER_SOFTWARE"=>"lighttpd/1.4.5", "HTTP_COOKIE"=>"_session_id=c84ace84796670c052c6ceb2451fb0f2; is_admin=yes", "HTTP_X_FORWARDED_SERVER"=>"glu.ttono.us", "REQUEST_URI"=>"/admin", "DOCUMENT_ROOT"=>"/home/kevinc/sites/typo/public", "SERVER_PORT"=>"8007", "QUERY_STRING"=>"", "REMOTE_PORT"=>"63137", "GATEWAY_INTERFACE"=>"CGI/1.1", "HTTP_X_FORWARDED_FOR"=>"65.88.180.234", "HTTP_ACCEPT"=>"*/*", "SCRIPT_FILENAME"=>"/home/kevinc/sites/typo/public/dispatch.fcgi", "REDIRECT_STATUS"=>"200", "REQUEST_METHOD"=>"GET"} + @env = { + "HTTP_MAX_FORWARDS" => "10", + "SERVER_NAME" => "glu.ttono.us:8007", + "FCGI_ROLE" => "RESPONDER", + "HTTP_X_FORWARDED_HOST" => "glu.ttono.us", + "HTTP_ACCEPT_ENCODING" => "gzip, deflate", + "HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en)", + "PATH_INFO" => "", + "HTTP_ACCEPT_LANGUAGE" => "en", + "HTTP_HOST" => "glu.ttono.us:8007", + "SERVER_PROTOCOL" => "HTTP/1.1", + "REDIRECT_URI" => "/dispatch.fcgi", + "SCRIPT_NAME" => "/dispatch.fcgi", + "SERVER_ADDR" => "207.7.108.53", + "REMOTE_ADDR" => "207.7.108.53", + "SERVER_SOFTWARE" => "lighttpd/1.4.5", + "HTTP_COOKIE" => "_session_id=c84ace84796670c052c6ceb2451fb0f2; is_admin=yes", + "HTTP_X_FORWARDED_SERVER" => "glu.ttono.us", + "REQUEST_URI" => "/admin", + "DOCUMENT_ROOT" => "/home/kevinc/sites/typo/public", + "SERVER_PORT" => "8007", + "QUERY_STRING" => "", + "REMOTE_PORT" => "63137", + "GATEWAY_INTERFACE" => "CGI/1.1", + "HTTP_X_FORWARDED_FOR" => "65.88.180.234", + "HTTP_ACCEPT" => "*/*", + "SCRIPT_FILENAME" => "/home/kevinc/sites/typo/public/dispatch.fcgi", + "REDIRECT_STATUS" => "200", + "REQUEST_METHOD" => "GET" + } # some Nokia phone browsers omit the space after the semicolon separator. # some developers have grown accustomed to using comma in cookie values. @alt_cookie_fmt_request_hash = {"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"} @@ -118,7 +147,7 @@ def test_body_should_be_rewound class RackResponseTest < BaseRackTest def setup super - @response = ActionController::RackResponse.new + @response = ActionController::RackResponse.new(@request) @output = StringIO.new('') end @@ -127,7 +156,7 @@ def test_simple_output status, headers, body = @response.out(@output) assert_equal 200, status - assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => ""}, headers) + assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) parts = [] body.each { |part| parts << part } @@ -141,10 +170,29 @@ def test_streaming_block status, headers, body = @response.out(@output) assert_equal 200, status - assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => ""}, headers) + assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) parts = [] body.each { |part| parts << part } assert_equal ["0", "1", "2", "3", "4"], parts end + + def test_set_session_cookie + cookie = CGI::Cookie.new({"name" => "name", "value" => "Josh"}) + @request.cgi.send :instance_variable_set, '@output_cookies', [cookie] + + @response.body = "Hello, World!" + + status, headers, body = @response.out(@output) + assert_equal 200, status + assert_equal({ + "Content-Type" => "text/html", + "Cache-Control" => "no-cache", + "Set-Cookie" => ["name=Josh; path="] + }, headers) + + parts = [] + body.each { |part| parts << part } + assert_equal ["Hello, World!"], parts + end end -- GitLab