Permalink
Browse files

Add support for cache headers

  • Loading branch information...
1 parent c36a447 commit 7e93aeafb0b2ba74000506853cc71e20b4fa9e86 Ben Marini committed Feb 4, 2011
View
1 lib/rack/gridfs.rb
@@ -1,4 +1,3 @@
-require 'timeout'
require 'mongo'
module Rack
View
62 lib/rack/gridfs/endpoint.rb
@@ -1,61 +1,13 @@
+require 'rack/gridfs/endpoint/base'
+require 'rack/gridfs/endpoint/caching'
+require 'rack/gridfs/endpoint/connection'
+
module Rack
class GridFS
class Endpoint
-
- def initialize(options = {})
- options = {
- :hostname => 'localhost',
- :port => Mongo::Connection::DEFAULT_PORT,
- :lookup => :id
- }.merge(options)
-
- @lookup = options[:lookup]
- @db = options[:db]
- @mapper = options[:mapper]
-
- @hostname, @port, @database, @username, @password =
- options.values_at(:hostname, :port, :database, :username, :password)
- end
-
- def call(env)
- gridfs_request( identifier_for_path(env['PATH_INFO']) )
- end
-
- def identifier_for_path(path)
- @mapper.respond_to?(:call) ? @mapper.call(path) : path
- end
-
- def db
- @db || connect!
- end
-
- private
-
- def connect!
- Timeout::timeout(5) do
- @db = Mongo::Connection.new(@hostname, @port).db(@database)
- @db.authenticate(@username, @password) if @username
- end
-
- return @db
- rescue Exception => e
- raise Rack::GridFSConnectionError, "Unable to connect to the MongoDB server (#{e.to_s})"
- end
-
- def gridfs_request(identifier)
- file = find_file(identifier)
- [200, {'Content-Type' => file.content_type}, file]
- rescue Mongo::GridFileNotFound, BSON::InvalidObjectId
- [404, {'Content-Type' => 'text/plain'}, ['File not found.']]
- end
-
- def find_file(identifier)
- 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")
- end
- end
-
+ include Base
+ include Connection
+ include Caching
end
end
end
View
52 lib/rack/gridfs/endpoint/base.rb
@@ -0,0 +1,52 @@
+module Rack
+ class GridFS
+ class Endpoint
+ module Base
+
+ def initialize(options = {})
+ @options = {
+ :hostname => 'localhost',
+ :port => Mongo::Connection::DEFAULT_PORT,
+ :lookup => :id
+ }.merge(options)
+
+ @lookup = @options[:lookup]
+ @mapper = @options[:mapper]
+ end
+
+ def call(env)
+ gridfs_request( identifier_for_path(env['PATH_INFO']) )
+ end
+
+ def identifier_for_path(path)
+ @mapper.respond_to?(:call) ? @mapper.call(path) : path
+ end
+
+ def db
+ @options[:db]
+ end
+
+ protected
+
+ def gridfs_request(identifier)
+ file = find_file(identifier)
+ [200, headers(file), file]
+ rescue Mongo::GridFileNotFound, BSON::InvalidObjectId
+ [404, {'Content-Type' => 'text/plain'}, ['File not found.']]
+ end
+
+ def find_file(identifier)
+ 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")
+ end
+ end
+
+ def headers(file)
+ { "Content-Type" => file.content_type }
+ end
+
+ end
+ end
+ end
+end
View
31 lib/rack/gridfs/endpoint/caching.rb
@@ -0,0 +1,31 @@
+module Rack
+ class GridFS
+ class Endpoint
+
+ module Caching
+ def initialize(*)
+ super
+ @options[:expires] ||= false
+ end
+
+ protected
+
+ def headers(file)
+ super.merge( cache_control_header(file) )
+ end
+
+ private
+
+ def cache_control_header(file)
+ if @options[:expires]
+ { "Cache-Control" => "max-age=#{@options[:expires]}, public" }
+ else
+ {}
+ end
+ end
+
+ end
+
+ end
+ end
+end
View
36 lib/rack/gridfs/endpoint/connection.rb
@@ -0,0 +1,36 @@
+require 'timeout'
+
+module Rack
+ class GridFS
+ class Endpoint
+
+ module Connection
+ def initialize(*)
+ super
+
+ @hostname, @port, @database, @username, @password =
+ @options.values_at(:hostname, :port, :database, :username, :password)
+ end
+
+ def db
+ @db ||= (super || connect!)
+ end
+
+ protected
+
+ def connect!
+ database = nil
+
+ Timeout::timeout(5) do
+ database = Mongo::Connection.new(@hostname, @port).db(@database)
+ database.authenticate(@username, @password) if @username
+ end
+
+ return database
+ rescue Exception => e
+ raise Rack::GridFSConnectionError, "Unable to connect to the MongoDB server (#{e.to_s})"
+ end
+ end
+ end
+ end
+end
View
26 test/caching_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+class Rack::GridFSTest < Test::Unit::TestCase
+ include Rack::Test::Methods
+ include Rack::GridFS::Test::Methods
+
+ context "Rack::GridFS::Endpoint::Caching" do
+ setup do
+ def app
+ setup_app(:lookup => :path, :expires => 1800)
+ end
+
+ @text_file = load_artifact('test.txt', nil, path='text')
+ @html_file = load_artifact('test.html', nil, path='html')
+ end
+
+ teardown do
+ db.collection('fs.files').remove
+ end
+
+ should "set expires header" do
+ get "/gridfs/#{@text_file.filename}"
+ assert_cache_control "max-age=1800, public"
+ end
+ end
+end
View
7 test/test_helper.rb
@@ -56,6 +56,13 @@ def load_artifact(filename, content_type, path=nil)
end
end
+ def assert_cache_control(cache_control)
+ assert_equal_header cache_control, "Cache-Control"
+ end
+
+ def assert_equal_header(expected, header)
+ assert_equal expected, last_response.headers[header]
+ end
end
end
end

0 comments on commit 7e93aea

Please sign in to comment.