lib/roda/plugins/halt.rb
# frozen-string-literal: true # class Roda module RodaPlugins # The halt plugin augments the standard request +halt+ method to allow the response # status, body, or headers to be changed when halting. # # After loading the halt plugin: # # plugin :halt # # You can call the halt method with an integer to set the response status and return: # # route do |r| # r.halt(403) # end # # Or set the response body and return: # # route do |r| # r.halt('body') # end # # Or set both: # # route do |r| # r.halt(403, 'body') # end # # Or set response status, headers, and body: # # route do |r| # r.halt(403, {'Content-Type'=>'text/csv'}, 'body') # end # # As supported by default, you can still pass an array which contains a rack response: # # route do |r| # r.halt([403, {'Content-Type'=>'text/csv'}, ['body']]) # end # # Note that there is a difference between providing status, headers, and body as separate # arguments and providing them as a single rack response array. With a rack response array, # the values are used directly, while with 3 arguments, the headers given are merged into # the existing headers and the given body is written to the existing response body. # # If using other plugins that recognize additional types of match block responses, such # as +symbol_views+ and +json+, you can pass those additional types to +r.halt+: # # plugin :halt # plugin :symbol_views # plugin :json # route do |r| # # symbol_views plugin, specifying template file to render as body # r.halt(:template) if r.params['a'] # # # symbol_views plugin, specifying status code, headers, and template file to render as body # r.halt(500, {'header'=>'value'}, :other_template) if r.params['c'] # # # json plugin, specifying status code and JSON body # r.halt(500, [{'error'=>'foo'}]) if r.params['b'] # end # # Note that when using the +json+ plugin with the +halt+ plugin, you cannot return a # array as a single argument and have it be converted to json, since it would be interpreted # as a rack response. You must use call +r.halt+ with either two or three argument forms # in that case. module Halt module RequestMethods # Expand default halt method to handle status codes, headers, and bodies. See Halt. def halt(*res) case res.length when 0 # do nothing when 1 case v = res[0] when Integer response.status = v when Array throw :halt, v else if result = block_result_body(v) response.write(result) else raise Roda::RodaError, "singular argument given to #halt not handled: #{v.inspect}" end end when 2 resp = response resp.status = res[0] resp.write(block_result_body(res[1])) when 3 resp = response resp.status = res[0] resp.headers.merge!(res[1]) resp.write(block_result_body(res[2])) else raise Roda::RodaError, "too many arguments given to #halt (accepts 0-3, received #{res.length})" end super() end end end register_plugin(:halt, Halt) end end