diff options
author | Brian Candler <b.candler@pobox.com> | 2009-03-05 13:17:42 +0000 |
---|---|---|
committer | Ryan Tomayko <rtomayko@gmail.com> | 2009-03-05 19:53:52 -0800 |
commit | fbb2ae41992fe609c0d004f13605ad0f8fc46c81 (patch) | |
tree | 35ff232b544fdfdddaa3651be1c66ff3bfd3e540 | |
parent | 91cea704e1c19ad0fe5c3f349fdf38a0fd747d9b (diff) | |
download | rack-fbb2ae41992fe609c0d004f13605ad0f8fc46c81.tar.gz |
Add Rack::ContentType middleware
Signed-off-by: Ryan Tomayko <rtomayko@gmail.com>
-rw-r--r-- | lib/rack.rb | 1 | ||||
-rw-r--r-- | lib/rack/content_type.rb | 23 | ||||
-rw-r--r-- | test/spec_rack_content_type.rb | 30 |
3 files changed, 54 insertions, 0 deletions
diff --git a/lib/rack.rb b/lib/rack.rb index c64bfe4f..26436307 100644 --- a/lib/rack.rb +++ b/lib/rack.rb @@ -31,6 +31,7 @@ module Rack autoload :CommonLogger, "rack/commonlogger" autoload :ConditionalGet, "rack/conditionalget" autoload :ContentLength, "rack/content_length" + autoload :ContentType, "rack/content_type" autoload :File, "rack/file" autoload :Deflater, "rack/deflater" autoload :Directory, "rack/directory" diff --git a/lib/rack/content_type.rb b/lib/rack/content_type.rb new file mode 100644 index 00000000..0c1e1ca3 --- /dev/null +++ b/lib/rack/content_type.rb @@ -0,0 +1,23 @@ +require 'rack/utils' + +module Rack + + # Sets the Content-Type header on responses which don't have one. + # + # Builder Usage: + # use Rack::ContentType, "text/plain" + # + # When no content type argument is provided, "text/html" is assumed. + class ContentType + def initialize(app, content_type = "text/html") + @app, @content_type = app, content_type + end + + def call(env) + status, headers, body = @app.call(env) + headers = Utils::HeaderHash.new(headers) + headers['Content-Type'] ||= @content_type + [status, headers.to_hash, body] + end + end +end diff --git a/test/spec_rack_content_type.rb b/test/spec_rack_content_type.rb new file mode 100644 index 00000000..9975b94d --- /dev/null +++ b/test/spec_rack_content_type.rb @@ -0,0 +1,30 @@ +require 'rack/mock' +require 'rack/content_type' + +context "Rack::ContentType" do + specify "sets Content-Type to default text/html if none is set" do + app = lambda { |env| [200, {}, "Hello, World!"] } + status, headers, body = Rack::ContentType.new(app).call({}) + headers['Content-Type'].should.equal 'text/html' + end + + specify "sets Content-Type to chosen default if none is set" do + app = lambda { |env| [200, {}, "Hello, World!"] } + status, headers, body = + Rack::ContentType.new(app, 'application/octet-stream').call({}) + headers['Content-Type'].should.equal 'application/octet-stream' + end + + specify "does not change Content-Type if it is already set" do + app = lambda { |env| [200, {'Content-Type' => 'foo/bar'}, "Hello, World!"] } + status, headers, body = Rack::ContentType.new(app).call({}) + headers['Content-Type'].should.equal 'foo/bar' + end + + specify "case insensitive detection of Content-Type" do + app = lambda { |env| [200, {'CONTENT-Type' => 'foo/bar'}, "Hello, World!"] } + status, headers, body = Rack::ContentType.new(app).call({}) + headers.to_a.select { |k,v| k.downcase == "content-type" }. + should.equal [["CONTENT-Type","foo/bar"]] + end +end |