diff --git a/lib/lotus/action/mime.rb b/lib/lotus/action/mime.rb index 409b2aa0..09ad7c37 100644 --- a/lib/lotus/action/mime.rb +++ b/lib/lotus/action/mime.rb @@ -1,3 +1,5 @@ +require 'rack/utils' +require 'lotus/utils' require 'lotus/utils/kernel' module Lotus @@ -415,7 +417,7 @@ def accept # @api private def accepts unless accept == DEFAULT_ACCEPT - ::Rack::Utils.best_q_match(accept, ::Rack::Mime::MIME_TYPES.values) + best_q_match(accept, ::Rack::Mime::MIME_TYPES.values) end end @@ -446,6 +448,34 @@ def content_type_with_charset "#{content_type}; charset=#{charset}" end + # Patched version of Rack::Utils.best_q_match. + # + # @since x.x.x + # @api private + # + # @see http://www.rubydoc.info/gems/rack/Rack/Utils#best_q_match-class_method + # @see https://github.com/rack/rack/pull/659 + # @see https://github.com/lotus/controller/issues/59 + # @see https://github.com/lotus/controller/issues/104 + def best_q_match(q_value_header, available_mimes) + values = ::Rack::Utils.q_values(q_value_header) + + values = values.map do |req_mime, quality| + match = available_mimes.find { |am| ::Rack::Mime.match?(am, req_mime) } + next unless match + [match, quality] + end.compact + + # See https://github.com/lotus/controller/issues/59 + # See https://github.com/lotus/controller/issues/104 + values = values.reverse unless Lotus::Utils.jruby? + + value = values.sort_by do |match, quality| + (match.split('/', 2).count('*') * -10) + quality + end.last + + value.first if value + end end end end diff --git a/lib/lotus/controller.rb b/lib/lotus/controller.rb index f68fcd79..a78d2907 100644 --- a/lib/lotus/controller.rb +++ b/lib/lotus/controller.rb @@ -2,7 +2,6 @@ require 'lotus/action' require 'lotus/controller/configuration' require 'lotus/controller/version' -require 'rack-patch' module Lotus # A set of logically grouped actions diff --git a/lib/rack-patch.rb b/lib/rack-patch.rb deleted file mode 100644 index a30ba2c9..00000000 --- a/lib/rack-patch.rb +++ /dev/null @@ -1,28 +0,0 @@ -# see https://github.com/rack/rack/pull/659 -require 'rack' -require 'lotus/utils' - -if Rack.release <= '1.5' - require 'rack/utils' - - Rack::Utils.class_eval do - def self.best_q_match(q_value_header, available_mimes) - values = q_values(q_value_header) - - values = values.map do |req_mime, quality| - match = available_mimes.find { |am| Rack::Mime.match?(am, req_mime) } - next unless match - [match, quality] - end.compact - - # See https://github.com/lotus/controller/issues/59 - values = values.reverse if RUBY_VERSION >= '2.2.0' || Lotus::Utils.rubinius? - - value = values.sort_by do |match, quality| - (match.split('/', 2).count('*') * -10) + quality - end.last - - value.first if value - end - end -end diff --git a/test/action/format_test.rb b/test/action/format_test.rb index 84fa2575..aa1b2e66 100644 --- a/test/action/format_test.rb +++ b/test/action/format_test.rb @@ -49,6 +49,16 @@ def call(params) status.must_equal 200 end + # Bug + # See https://github.com/lotus/controller/issues/104 + it "accepts 'text/html, application/xhtml+xml, image/jxr, */*' and returns :html" do + status, headers, _ = @action.call({ 'HTTP_ACCEPT' => 'text/html, application/xhtml+xml, image/jxr, */*' }) + + @action.format.must_equal :html + headers['Content-Type'].must_equal 'text/html; charset=utf-8' + status.must_equal 200 + end + mime_types = ['application/octet-stream', 'text/html'] Rack::Mime::MIME_TYPES.each do |format, mime_type| next if mime_types.include?(mime_type)