Module: Sinatra::RestHelpers
- Defined in:
- lib/sinatra/rest_helpers.rb
Overview
Constant Summary collapse
- INFINITY =
1/0.0
Instance Method Summary collapse
-
#compute_etag(*args) ⇒ Object
:nodoc:.
-
#parse_input_data!(parser_selector, options = {:limit => 10*1024}) ⇒ Object
parser_selector must respond to :select(content_type) and return a parser object with a :load method.
-
#provides(*formats) ⇒ Object
e.g.: get ‘/x/y/z’ do provides “application/json”, :xml, :zip, “text/html;level=5” end.
Instance Method Details
#compute_etag(*args) ⇒ Object
:nodoc:
65 66 67 68 |
# File 'lib/sinatra/rest_helpers.rb', line 65 def compute_etag(*args) # :nodoc: raise ArgumentError, "You must provide at least one parameter for the ETag computation" if args.empty? Digest::SHA1.hexdigest(args.join(".")) end |
#parse_input_data!(parser_selector, options = {:limit => 10*1024}) ⇒ Object
parser_selector must respond to :select(content_type) and return a parser object with a :load method.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/sinatra/rest_helpers.rb', line 50 def parse_input_data!(parser_selector, = {:limit => 10*1024}) case (mime_type = request.env['CONTENT_TYPE']) when nil halt 400, "You must provide a Content-Type HTTP header." when /application\/x-www-form-urlencoded/i request.env['rack.request.form_hash'] else input_data = request.env['rack.input'].read halt 400, "Input data size must not be empty and must not exceed #{[:limit]} bytes." if ([:limit] && input_data.length > [:limit]) || input_data.length == 0 parser_selector.select(mime_type).load(input_data) end rescue StandardError => e halt 400, "#{e.class.name}: #{e.}" end |
#provides(*formats) ⇒ Object
e.g.:
get '/x/y/z' do
provides "application/json", :xml, :zip, "text/html;level=5"
end
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/sinatra/rest_helpers.rb', line 17 def provides *formats generate_type_hash = Proc.new{ |header| type, *params = header.split(/;\s*/) Hash[*params.map{|p| p.split(/\s*=\s*/)}.flatten].merge("type" => type) } supported_formats = formats.map do |f| # selects the correct mime type if a symbol is given f.is_a?(Symbol) ? ::Rack::Mime::MIME_TYPES[".#{f.to_s}"] : f end.compact.map do |f| generate_type_hash.call(f) end # request.accept is an Array accepted_formats = request.accept.map do |f| generate_type_hash.call(f) end selected_format = supported_formats.detect{ |supported_format| !accepted_formats.detect{ |accepted_format| Regexp.new(Regexp.escape(accepted_format["type"]).gsub("\\*", ".*?"), Regexp::IGNORECASE) =~ supported_format["type"] && (accepted_format["level"] || INFINITY).to_f >= (supported_format["level"] || 0).to_f }.nil? } if selected_format.nil? halt 406, supported_formats.map{|f| output = f["type"] output.concat(";level=#{f["level"]}") if f.has_key?("level") output }.join(",") else response.headers['Content-Type'] = "#{selected_format["type"]}#{selected_format["level"].nil? ? "" : ";level=#{selected_format["level"]}"}" end end |