Public Instance methods
chunked(template, opts=OPTS, &block)
Render
a response to the user in chunks. See Chunked
for an overview. If a block is given, it is passed to delay
.
[show source]
# File lib/roda/plugins/chunked.rb 227 def chunked(template, opts=OPTS, &block) 228 unless defined?(@_chunked) 229 @_chunked = !self.opts[:force_chunked_encoding] || @_request.http_version == "HTTP/1.1" 230 end 231 232 if block 233 delay(&block) 234 end 235 236 unless @_chunked 237 # If chunking is disabled, do a normal rendering of the view. 238 run_delayed_blocks 239 return view(template, opts) 240 end 241 242 if template.is_a?(Hash) 243 if opts.empty? 244 opts = template 245 else 246 opts = Hash[opts].merge!(template) 247 end 248 end 249 250 # Hack so that the arguments don't need to be passed 251 # through the response and body objects. 252 @_each_chunk_args = [template, opts] 253 254 res = response 255 headers = res.headers 256 if chunk_headers = self.opts[:chunk_headers] 257 headers.merge!(chunk_headers) 258 end 259 if self.opts[:force_chunked_encoding] 260 res[RodaResponseHeaders::TRANSFER_ENCODING] = 'chunked' 261 body = Body.new(self) 262 else 263 body = StreamBody.new(self) 264 end 265 266 throw :halt, res.finish_with_body(body) 267 end
delay(&block)
Delay the execution of the block until right before the content template is to be rendered.
[show source]
# File lib/roda/plugins/chunked.rb 271 def delay(&block) 272 raise RodaError, "must pass a block to Roda#delay" unless block 273 (@_delays ||= []) << block 274 end
each_chunk()
Yield each chunk of the template rendering separately.
[show source]
# File lib/roda/plugins/chunked.rb 277 def each_chunk 278 response.body.each{|s| yield s} 279 280 template, opts = @_each_chunk_args 281 282 # Use a lambda for the flusher, so that a call to flush 283 # by a template can result in this method yielding a chunk 284 # of the response. 285 @_flusher = lambda do 286 yield @_out_buf 287 @_out_buf = String.new 288 end 289 290 if layout_opts = view_layout_opts(opts) 291 @_out_buf = render_template(layout_opts) do 292 flush 293 run_delayed_blocks 294 yield opts[:content] || render_template(template, opts) 295 nil 296 end 297 else 298 run_delayed_blocks 299 yield view(template, opts) 300 end 301 302 flush 303 rescue => e 304 handle_chunk_error(e) 305 end
flush()
Call the flusher if one is defined. If one is not defined, this is a no-op, so flush can be used inside views without breaking things if chunking is not used.
[show source]
# File lib/roda/plugins/chunked.rb 315 def flush 316 @_flusher.call if @_flusher 317 end
handle_chunk_error(e)
By default, raise the exception.
[show source]
# File lib/roda/plugins/chunked.rb 308 def handle_chunk_error(e) 309 raise e 310 end
no_chunk!()
Disable chunking for the current request. Mostly useful when chunking is turned on by default.
[show source]
# File lib/roda/plugins/chunked.rb 211 def no_chunk! 212 @_chunked = false 213 end
view(*a)
If chunking by default, call chunked if it hasn’t yet been called and chunking is not specifically disabled.
[show source]
# File lib/roda/plugins/chunked.rb 217 def view(*a) 218 if opts[:chunk_by_default] && !defined?(@_chunked) && !defined?(yield) 219 chunked(*a) 220 else 221 super 222 end 223 end