From 389d15ef139e50696b274f2d61dd309ba2632877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 18 Apr 2011 08:52:29 +0200 Subject: Body... wanna *stream* my body? Body... such a thrill my body! Added stream as class level method to make it explicit when to stream. Render also accepts :stream as option. --- .../lib/action_controller/metal/streaming.rb | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 actionpack/lib/action_controller/metal/streaming.rb (limited to 'actionpack/lib/action_controller/metal') diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb new file mode 100644 index 0000000000..adb3e94134 --- /dev/null +++ b/actionpack/lib/action_controller/metal/streaming.rb @@ -0,0 +1,57 @@ +require 'active_support/core_ext/file/path' +require 'rack/chunked' + +module ActionController #:nodoc: + # Methods for sending streaming templates back to the client. + module Streaming + extend ActiveSupport::Concern + + include AbstractController::Rendering + attr_internal :stream + + module ClassMethods + # Render streaming templates. It accepts :only, :except, :if and :unless as options + # to specify when to stream, as in ActionController filters. + def stream(options={}) + if defined?(Fiber) + before_filter :_stream_filter, options + else + raise "You cannot use streaming if Fiber is not available." + end + end + end + + protected + + # Mark following render calls as streaming. + def _stream_filter #:nodoc: + self.stream = true + end + + # Consider the stream option when normalazing options. + def _normalize_options(options) #:nodoc: + super + options[:stream] = self.stream unless options.key?(:stream) + end + + # Set proper cache control and transfer encoding when streaming + def _process_options(options) #:nodoc: + super + if options[:stream] + headers["Cache-Control"] ||= "no-cache" + headers["Transfer-Encoding"] = "chunked" + headers.delete("Content-Length") + end + end + + # Call render_to_body if we are streaming instead of usual +render+. + def _render_template(options) #:nodoc: + if options.delete(:stream) + Rack::Chunked::Body.new view_context.render_body(options) + else + super + end + end + end +end + \ No newline at end of file -- cgit v1.2.3