Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Correct some of the mime type issues. References #316 and #366.

HTTP 1.0 and 1.1 do not have MUST for Content-Type requirements, they have "should" (not SHOULD). They also have text describing how clients should handle this header being missing.
  • Loading branch information...
commit c72121aa0fcaebc5e38365f50ea1f9be52cc3a06 1 parent fb362aa
@raggi raggi authored
View
19 lib/rack/file.rb
@@ -21,9 +21,10 @@ class File
alias :to_path :path
- def initialize(root, cache_control = nil)
+ def initialize(root, cache_control = nil, default_mime = 'text/plain')
@root = root
@cache_control = cache_control
+ @default_mime = default_mime
end
def call(env)
@@ -70,15 +71,13 @@ def _call(env)
def serving(env)
last_modified = F.mtime(@path).httpdate
return [304, {}, []] if env['HTTP_IF_MODIFIED_SINCE'] == last_modified
- response = [
- 200,
- {
- "Last-Modified" => last_modified,
- "Content-Type" => Mime.mime_type(F.extname(@path), 'text/plain')
- },
- env["REQUEST_METHOD"] == "HEAD" ? [] : self
- ]
- response[1].merge! 'Cache-Control' => @cache_control if @cache_control
+
+ headers = { "Last-Modified" => last_modified }
+ mime = Mime.mime_type(F.extname(@path), @default_mime)
+ headers["Content-Type"] = mime if mime
+ headers['Cache-Control'] = @cache_control if @cache_control
+
+ response = [ 200, headers, env["REQUEST_METHOD"] == "HEAD" ? [] : self ]
# NOTE:
# We check via File::size? whether this file provides size info
View
7 lib/rack/lint.rb
@@ -474,9 +474,10 @@ def check_content_type(status, headers)
return
end
}
- assert("No Content-Type header found") {
- Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
- }
+ # This is a SHOULD in HTTP 1.0 and 1.1:
+ # assert("No Content-Type header found") {
+ # Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
+ # }
end
## === The Content-Length
View
3  lib/rack/response.rb
@@ -21,8 +21,7 @@ class Response
def initialize(body=[], status=200, header={})
@status = status.to_i
- @header = Utils::HeaderHash.new("Content-Type" => "text/html").
- merge(header)
+ @header = Utils::HeaderHash.new.merge(header)
@chunked = "chunked" == @header['Transfer-Encoding']
@writer = lambda { |x| @body << x }
View
21 test/spec_file.rb
@@ -180,4 +180,25 @@
res['Content-Length'].should.equal "193"
end
+ should "default to a mime type of text/plain" do
+ req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
+ res = req.get "/cgi/test"
+ res.should.be.successful
+ res['Content-Type'].should.equal "text/plain"
+ end
+
+ should "allow the default mime type to be set" do
+ req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT, nil, 'application/octet-stream')))
+ res = req.get "/cgi/test"
+ res.should.be.successful
+ res['Content-Type'].should.equal "application/octet-stream"
+ end
+
+ should "not set Content-Type if the mime type is not set" do
+ req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT, nil, nil)))
+ res = req.get "/cgi/test"
+ res.should.be.successful
+ res['Content-Type'].should.equal nil
+ end
+
end
View
12 test/spec_lint.rb
@@ -234,12 +234,12 @@ def result.name
end
should "notice content-type errors" do
- lambda {
- Rack::Lint.new(lambda { |env|
- [200, {"Content-length" => "0"}, []]
- }).call(env({}))
- }.should.raise(Rack::Lint::LintError).
- message.should.match(/No Content-Type/)
+ # lambda {
+ # Rack::Lint.new(lambda { |env|
+ # [200, {"Content-length" => "0"}, []]
+ # }).call(env({}))
+ # }.should.raise(Rack::Lint::LintError).
+ # message.should.match(/No Content-Type/)
[100, 101, 204, 205, 304].each do |status|
lambda {
View
25 test/spec_mime.rb
@@ -0,0 +1,25 @@
+require 'rack/mime'
+
+describe Rack::Mime do
+
+ it "should return the fallback mime-type for files with no extension" do
+ fallback = 'image/jpg'
+ Rack::Mime.mime_type(File.extname('no_ext'), fallback).should == fallback
+ end
+
+ it "should always return 'application/octet-stream' for unknown file extensions" do
+ unknown_ext = File.extname('unknown_ext.abcdefg')
+ Rack::Mime.mime_type(unknown_ext).should == 'application/octet-stream'
+ end
+
+ it "should return the mime-type for a given extension" do
+ # sanity check. it would be infeasible test every single mime-type.
+ Rack::Mime.mime_type(File.extname('image.jpg')).should == 'image/jpeg'
+ end
+
+ it "should support null fallbacks" do
+ Rack::Mime.mime_type('.nothing', nil).should == nil
+ end
+
+end
+
View
6 test/spec_response.rb
@@ -6,7 +6,7 @@
response = Rack::Response.new
status, header, body = response.finish
status.should.equal 200
- header.should.equal "Content-Type" => "text/html"
+ header.should.equal({})
body.each { |part|
part.should.equal ""
}
@@ -14,7 +14,7 @@
response = Rack::Response.new
status, header, body = *response
status.should.equal 200
- header.should.equal "Content-Type" => "text/html"
+ header.should.equal({})
body.each { |part|
part.should.equal ""
}
@@ -37,7 +37,7 @@
it "can set and read headers" do
response = Rack::Response.new
- response["Content-Type"].should.equal "text/html"
+ response["Content-Type"].should.equal nil
response["Content-Type"] = "text/plain"
response["Content-Type"].should.equal "text/plain"
end
Please sign in to comment.
Something went wrong with that request. Please try again.