module Roda::RodaPlugins::Chunked::InstanceMethods
def chunked(template, opts=OPTS, &block)
Render a response to the user in chunks. See Chunked for
def chunked(template, opts=OPTS, &block) unless defined?(@_chunked) @_chunked = env[HTTP_VERSION] == HTTP11 end unless @_chunked # If chunking is disabled, do a normal rendering of the view. yield if block return view(template, opts) end if template.is_a?(Hash) if opts.empty? opts = template else opts = opts.merge(template) end end # Hack so that the arguments don't need to be passed # through the response and body objects. @_each_chunk_args = [template, opts, block] res = response headers = res.headers if chunk_headers = self.opts[:chunk_headers] headers.merge!(chunk_headers) end headers[TRANSFER_ENCODING] = CHUNKED throw :halt, res.finish_with_body(Body.new(self)) end
def each_chunk
def each_chunk response.body.each{|s| yield s} template, opts, block = @_each_chunk_args # Use a lambda for the flusher, so that a call to flush # by a template can result in this method yielding a chunk # of the response. @_flusher = lambda do yield @_out_buf @_out_buf = '' end if layout = opts.fetch(:layout, render_opts[:layout]) if layout_opts = opts[:layout_opts] layout_opts = render_opts[:layout_opts].merge(layout_opts) end @_out_buf = render(layout, layout_opts||OPTS) do flush block.call if block yield opts[:content] || render(template, opts) nil end else yield if block yield view(template, opts) end flush rescue => e handle_chunk_error(e) end
def flush
is a no-op, so flush can be used inside views without breaking
Call the flusher if one is defined. If one is not defined, this
def flush @_flusher.call if @_flusher end
def handle_chunk_error(e)
def handle_chunk_error(e) raise e end
def no_chunk!
Disable chunking for the current request. Mostly useful when
def no_chunk! @_chunked = false end
def view(*a)
If chunking by default, call chunked if it hasn't yet been
def view(*a) if opts[:chunk_by_default] && !defined?(@_chunked) chunked(*a) else super end end