From 0ca74ebf7ec1af2826ea980e19f922816e483ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franc=CC=A7ois=20Beausoleil?= Date: Thu, 9 May 2013 18:44:29 -0400 Subject: [PATCH] Fallback to default_content if wildcard present in Accept header If a browser makes a request like this: Accept: text/csv,*.* And the application is implemented like this: set :default_content, :html get "/" do respond_to do |wants| format.html { erb :home } end end The request would return a 404, even though the caller specifically said it was ready to accept any mime type. I found this when building an API that does not return HTML: it returns JSON or CSV, but browsers request HTML, XHTML and */*, in this order. By catering to what the caller asked for, the API is more easily explorable in a browser. --- lib/sinatra/respond_to.rb | 6 +++++- spec/extension_spec.rb | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/sinatra/respond_to.rb b/lib/sinatra/respond_to.rb index bca5029..0946d24 100644 --- a/lib/sinatra/respond_to.rb +++ b/lib/sinatra/respond_to.rb @@ -215,7 +215,11 @@ def wants.method_missing(type, *args, &handler) request.accept.each do |mime_type| break if alt = wants.keys.detect {|k| ::Sinatra::Base.mime_type(k) == mime_type} end - format alt if alt + if alt + format alt + elsif request.accept.include?("*.*") + format settings.default_content + end end raise UnhandledFormat if wants[format].nil? wants[format].call diff --git a/spec/extension_spec.rb b/spec/extension_spec.rb index b859584..0fd31d6 100644 --- a/spec/extension_spec.rb +++ b/spec/extension_spec.rb @@ -186,6 +186,12 @@ def mime_type(sym) last_response.body.should =~ %r{'Hiya from javascript'} last_response.content_type.should include(mime_type(:js)) end + + it "should use default_content when the first Accept header includes the wildcard" do + get "/resource", {}, {'HTTP_ACCEPT' => "text/csv;q=0.9,*.*;q=0.8"} + last_response.body.should =~ %r{\s*\s*Hello from HTML\s*\s*} + last_response.content_type.should include(mime_type(:html)) + end end describe "routes not using respond_to" do