Browse files

Refactor condtional get support

  • Loading branch information...
1 parent 31539eb commit b500bb2e0a829ea38cf19129eac0a12480c6d249 @bmarini bmarini committed with ches Feb 6, 2011
Showing with 34 additions and 22 deletions.
  1. +14 −17 lib/rack/gridfs/endpoint/base.rb
  2. +5 −2 lib/rack/gridfs/endpoint/caching.rb
  3. +13 −2 test/gridfs_test.rb
  4. +2 −1 test/test_helper.rb
View
31 lib/rack/gridfs/endpoint/base.rb
@@ -16,7 +16,14 @@ def initialize(options = {})
def call(env)
request = Rack::Request.new(env)
- gridfs_request( identifier_for_path(env['PATH_INFO']), request )
+ id = identifier_for_path(request.path_info)
+ file = find_file(id)
+
+ response_for(file, request)
+ rescue Mongo::GridError, BSON::InvalidObjectId
+ [404, {'Content-Type' => 'text/plain'}, ['File not found.' + id]]
+ rescue Mongo::GridFileNotFound
+ [404, {'Content-Type' => 'text/plain'}, ['File not found.']]
end
def identifier_for_path(path)
@@ -29,29 +36,19 @@ def db
protected
- def gridfs_request(id, request)
- grid = Mongo::GridFileSystem.new(db)
- file = grid.open(id, 'r')
- if request.env['If-None-Match'] == file.files_id.to_s || request.env['If-Modified-Since'] == file.upload_date.httpdate
- [304, {'Content-Type' => 'text/plain', 'Etag' => file.files_id.to_s}, ['Not modified']]
- else
- [200, headers(file), [file.read]]
- end
- rescue Mongo::GridError, BSON::InvalidObjectId
- [404, {'Content-Type' => 'text/plain'}, ['File not found.' + id]]
- rescue Mongo::GridFileNotFound
- [404, {'Content-Type' => 'text/plain'}, ['File not found.']]
+ def response_for(file, request)
+ [ 200, headers(file), file ]
end
- def find_file(identifier)
+ def find_file(id_or_path)
case @lookup.to_sym
- when :id then Mongo::Grid.new(db).get(BSON::ObjectId.from_string(identifier))
- when :path then Mongo::GridFileSystem.new(db).open(identifier, "r")
+ when :id then Mongo::Grid.new(db).get(BSON::ObjectId.from_string(id_or_path))
+ when :path then Mongo::GridFileSystem.new(db).open(id_or_path, "r")
end
end
def headers(file)
- {'Content-Type' => file.content_type, 'Last-Modified' => file.upload_date.httpdate, 'Etag' => file.files_id.to_s}
+ { 'Content-Type' => file.content_type }
end
end
View
7 lib/rack/gridfs/endpoint/caching.rb
@@ -11,12 +11,15 @@ def initialize(*)
protected
def headers(file)
- super.merge( cache_control_header(file) )
+ super.merge(
+ 'Last-Modified' => file.upload_date.httpdate,
+ 'Etag' => file.files_id.to_s
+ ).merge(cache_control_header)
end
private
- def cache_control_header(file)
+ def cache_control_header
if @options[:expires]
{ "Cache-Control" => "max-age=#{@options[:expires]}, public" }
else
View
15 test/gridfs_test.rb
@@ -9,6 +9,17 @@ class Rack::GridFSTest < Test::Unit::TestCase
def app; setup_app end
end
+ should "load artifacts" do
+ image_id = load_artifact('3wolfmoon.jpg', 'image/jpeg')
+
+ file1 = Mongo::Grid.new(db).get(image_id)
+ file2 = Mongo::GridFileSystem.new(db).open('3wolfmoon.jpg', "r")
+ file3 = Mongo::Grid.new(db).get(BSON::ObjectId.from_string(image_id.to_s))
+
+ assert_equal file1.filename, file2.filename
+ assert_equal file2.filename, file3.filename
+ end
+
context "on initialization" do
setup do
@@ -151,14 +162,14 @@ def app; setup_app end
should "return 304 when Etag matches" do
image_id = load_artifact('3wolfmoon.jpg', 'image/jpeg')
gridfile = Mongo::Grid.new(db).get(image_id)
- get "/gridfs/3wolfmoon.jpg", nil, {'If-None-Match' => gridfile.files_id.to_s}
+ get "/gridfs/3wolfmoon.jpg", nil, {'HTTP_IF_NONE_MATCH' => gridfile.files_id.to_s}
assert_equal 304, last_response.status
end
should "return 304 when Last-Modified matches" do
image_id = load_artifact('3wolfmoon.jpg', 'image/jpeg')
gridfile = Mongo::Grid.new(db).get(image_id)
- get "/gridfs/3wolfmoon.jpg", nil, {'If-Modified-Since' => gridfile.upload_date.httpdate}
+ get "/gridfs/3wolfmoon.jpg", nil, {'HTTP_IF_MODIFIED_SINCE' => gridfile.upload_date.httpdate}
assert_equal 304, last_response.status
assert_equal gridfile.files_id.to_s, last_response.headers['Etag']
end
View
3 test/test_helper.rb
@@ -27,7 +27,7 @@ def stub_mongodb_connection
end
def test_database_options
- { :hostname => 'localhost', :port => 27017, :database => 'test', :prefix => 'gridfs' }
+ { :hostname => 'localhost', :port => 27017, :database => 'test', :prefix => 'gridfs', :lookup => :path }
end
def db
@@ -38,6 +38,7 @@ def setup_app(opts={})
gridfs_opts = test_database_options.merge(opts)
Rack::Builder.new do
+ use Rack::ConditionalGet
use Rack::GridFS, gridfs_opts
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
end

0 comments on commit b500bb2

Please sign in to comment.