Permalink
Browse files

raise exceptions on header set after response committed

  • Loading branch information...
1 parent 01b8126 commit 06c9e176ca1b74e99bc258295bfbd8d2f2f33563 @tenderlove tenderlove committed Jul 30, 2012
View
21 actionpack/lib/action_controller/metal/live.rb
@@ -1,4 +1,5 @@
require 'action_dispatch/http/response'
+require 'delegate'
module ActionController
module Live
@@ -30,6 +31,26 @@ def close
end
end
+ class Header < DelegateClass(Hash)
+ def initialize(response, header)
+ @response = response
+ super(header)
+ end
+
+ def []=(k,v)
+ if @response.committed?
+ raise ActionDispatch::IllegalStateError, 'header already sent'
+ end
+
+ super
+ end
+ end
+
+ def initialize(status = 200, header = {}, body = [])
+ header = Header.new self, header
+ super(status, header, body)
+ end
+
private
def build_buffer(response, body)
View
3 actionpack/lib/action_dispatch.rb
@@ -36,6 +36,9 @@ module Rack
module ActionDispatch
extend ActiveSupport::Autoload
+ class IllegalStateError < StandardError
+ end
+
autoload_under 'http' do
autoload :Request
autoload :Response
View
19 actionpack/test/dispatch/live_response_test.rb
@@ -40,6 +40,25 @@ def test_content_length_is_removed
@response.stream.write 'omg'
assert_nil @response.headers['Content-Length']
end
+
+ def test_headers_cannot_be_written_after_write
+ @response.stream.write 'omg'
+
+ e = assert_raises(ActionDispatch::IllegalStateError) do
+ @response.headers['Content-Length'] = "zomg"
+ end
+
+ assert_equal 'header already sent', e.message
+ end
+
+ def test_headers_cannot_be_written_after_close
+ @response.stream.close
+
+ e = assert_raises(ActionDispatch::IllegalStateError) do
+ @response.headers['Content-Length'] = "zomg"
+ end
+ assert_equal 'header already sent', e.message
+ end
end
end
end

0 comments on commit 06c9e17

Please sign in to comment.