rack-mogilefs 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.md ADDED
@@ -0,0 +1,8 @@
1
+ ## 0.1.2 (2010-09-09)
2
+
3
+ * Add a way to customize mapping of PATH_INFO to MogileFS keys
4
+ * Better test coverage
5
+
6
+ ## 0.1.1 (2010-09-08)
7
+
8
+ * First release
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # Rack middleware/endpoint for serving MogileFS files
1
+ # rack-mogilefs
2
+
3
+ If you are using Nginx you'll probably want to serve MogileFS files with
4
+ the [MogileFS Module](http://www.grid.net.ru/nginx/mogilefs.en.html), but if
5
+ you need to serve them out of a Rack app, this should help.
2
6
 
3
7
  ## Getting Started:
4
8
 
@@ -10,19 +14,19 @@ There are a variety of ways to use it:
10
14
 
11
15
  ### Rack middleware
12
16
  # (config.ru)
13
- use Rack::MogileFS, :path => %r{^/system/*}
17
+ use Rack::MogileFS, :path => %r{^/assets/*}
14
18
 
15
19
  ### Rails 3:
16
20
 
17
21
  # (config/routes.rb)
18
- match "/system/*" => Rack::MogileFS::Endpoint.new
22
+ match "/assets/*" => Rack::MogileFS::Endpoint.new
19
23
 
20
24
  ### Rails 2:
21
25
 
22
- # (app/metal/mogilefs.rb)
23
- class MogileFSMetal
26
+ # (app/metal/mogilefs_metal.rb)
27
+ class MogilefsMetal
24
28
  def self.call(env)
25
- if env["PATH_INFO"] =~ %r{^/system/*}
29
+ if env["PATH_INFO"] =~ %r{^/assets/*}
26
30
  Rack::MogileFS::Endpoint.new.call(env)
27
31
  else
28
32
  [ 404, { "Content-Type" => "text/html" }, ["Not Found"] ]
@@ -36,10 +40,19 @@ There are a variety of ways to use it:
36
40
  content type of the file is detected by the extension, using the `mime-types`
37
41
  gem.
38
42
 
43
+ If you want to customize the mapping of the PATH_INFO string to a MogileFS key
44
+ you can provide a mapper proc (or anything that responds to call) like this:
45
+
46
+ # map '/assets/filename.gif' to the mogilefs key 'filename.gif'
47
+ # Rack::MogileFS and Rack::MogileFS::Endpoint take the same options
48
+ use Rack::MogileFS,
49
+ :path => %r{^/assets/*},
50
+ :mapper => lambda { |path| path.sub('/assets/', '') }
51
+
39
52
  ## Configuration
40
53
 
41
- By default will look for a yaml config in `config/mogilefs.yml` that looks
42
- like this:
54
+ If `Rack::MogileFS` detects it is inside a Rails app, it will look for a yaml
55
+ config in `config/mogilefs.yml` that looks like this:
43
56
 
44
57
  development:
45
58
  connection:
@@ -52,7 +65,7 @@ like this:
52
65
  ...
53
66
 
54
67
 
55
- and initialize a mogilefs client like this:
68
+ and initialize a MogileFS client like this:
56
69
 
57
70
  config = YAML.load_file( Rails.root.join("config/mogilefs.yml") )[Rails.env]
58
71
  MogileFS::MogileFS.new( config["connection"].symbolize_keys )
data/Rakefile CHANGED
@@ -9,4 +9,12 @@ task :test do
9
9
  t.pattern = 'test/*_test.rb'
10
10
  t.verbose = true
11
11
  end
12
- end
12
+ end
13
+
14
+ desc 'Measures test coverage'
15
+ task :coverage do
16
+ rm_f "coverage"
17
+ rm_f "coverage.data"
18
+ system "rcov -x /Users -Ilib:test test/*_test.rb"
19
+ system "open coverage/index.html" if PLATFORM['darwin']
20
+ end
@@ -5,6 +5,7 @@ module Rack
5
5
  def initialize(options={})
6
6
  @options = {
7
7
  :client => nil,
8
+ :mapper => nil,
8
9
  :default_content_type => "image/png"
9
10
  }.merge(options)
10
11
 
@@ -12,10 +13,11 @@ module Rack
12
13
  end
13
14
 
14
15
  def call(env)
15
- data = client.get_file_data(env['PATH_INFO'])
16
- [ 200, { "Content-Type" => content_type(env['PATH_INFO']) }, [ data ] ]
17
- rescue ::MogileFS::Backend::UnknownKeyError
18
- [ 404, { "Content-Type" => "text/html" }, ["Not Found"] ]
16
+ path = key_for_path(env['PATH_INFO'].dup)
17
+ data = client.get_file_data(path)
18
+ [ 200, { "Content-Type" => content_type(path) }, [ data ] ]
19
+ rescue ::MogileFS::Backend::UnknownKeyError => e
20
+ [ 404, { "Content-Type" => "text/html" }, [e.message] ]
19
21
  rescue ::MogileFS::UnreachableBackendError => e
20
22
  [ 503, { "Content-Type" => "text/html" }, [e.message] ]
21
23
  rescue ::MogileFS::Error => e
@@ -24,6 +26,10 @@ module Rack
24
26
 
25
27
  protected
26
28
 
29
+ def key_for_path(path)
30
+ @options[:mapper].respond_to?(:call) ? @options[:mapper].call(path) : path
31
+ end
32
+
27
33
  def content_type(path_info)
28
34
  ext = path_info.split(".").last
29
35
  MIME::Types.type_for(ext).first.content_type
@@ -1,42 +1,85 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class TestMiddleWare < Test::Unit::TestCase
4
- class MockMogileFsClient
5
- def get_file_data(key)
6
- "Mock Data"
7
- end
4
+ def setup
5
+ @client = MockMogileFsClient.new
8
6
  end
9
7
 
10
- def test_middleware_with_path
11
- app = Rack::Builder.new do
12
- use Rack::Lint
13
- use Rack::MogileFS, :path => %r{^/system/*}
14
- use Rack::Lint
15
- run lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
16
- end
8
+ def test_path_matching
9
+ app_with :path => %r{^/assets/*}
10
+ get '/'
17
11
 
18
- response = Rack::MockRequest.new(app).get('/')
19
- assert_equal "Hello, World!", response.body
12
+ assert_body "Hello, World!"
13
+ end
14
+
15
+ def test_unreachable_exception
16
+ app_with :path => %r{^/assets/*}
17
+ get '/assets/unreachable.txt'
18
+
19
+ assert_status 503
20
+ assert_body "couldn't connect to mogilefsd backend"
21
+ end
22
+
23
+ def test_unknown_key_exception
24
+ @client.expects(:get_file_data).raises(MogileFS::Backend::UnknownKeyError)
25
+
26
+ app_with :path => %r{^/assets/*}, :client => @client
27
+ get '/assets/unknown.txt'
20
28
 
21
- response = Rack::MockRequest.new(app).get('/system/unreachable.txt')
22
- assert_equal "couldn't connect to mogilefsd backend", response.body
23
- assert_equal 503, response.status
29
+ assert_status 404
30
+ end
31
+
32
+ def test_mogilefs_exception
33
+ @client.expects(:get_file_data).raises(MogileFS::Error)
34
+
35
+ app_with :path => %r{^/assets/*}, :client => @client
36
+ get '/assets/error.txt'
37
+
38
+ assert_status 500
24
39
  end
25
40
 
26
41
  def test_middleware_with_mock_mogile_client
27
- app = Rack::Builder.new do
28
- use Rack::Lint
29
- use Rack::MogileFS, :path => %r{^/system/*}, :client => MockMogileFsClient.new
30
- use Rack::Lint
31
- run lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
32
- end
42
+ app_with :path => %r{^/assets/*}, :client => @client
43
+ get '/assets/asset.txt'
44
+
45
+ assert_body "Mock Data for /assets/asset.txt"
46
+ end
33
47
 
34
- response = Rack::MockRequest.new(app).get('/')
35
- assert_equal "Hello, World!", response.body
48
+ def test_content_type_lookup
49
+ app_with :path => %r{^/assets/*}, :client => @client
50
+ get '/assets/asset.txt'
36
51
 
37
- response = Rack::MockRequest.new(app).get('/system/mocked.txt')
38
- assert_equal "Mock Data", response.body
39
- assert_equal 200, response.status
40
- assert_equal "text/plain", response.headers['Content-Type']
52
+ assert_status 200
53
+ assert_content_type "text/plain"
54
+
55
+ get '/assets/asset.png'
56
+
57
+ assert_status 200
58
+ assert_content_type "image/png"
59
+
60
+ get '/assets/asset.xml'
61
+
62
+ assert_status 200
63
+ assert_content_type "application/xml"
41
64
  end
65
+
66
+ def test_default_content_type
67
+ app_with :path => %r{^/assets/*}, :client => @client
68
+ get '/assets/asset.xxx'
69
+
70
+ assert_status 200
71
+ assert_content_type "image/png"
72
+ end
73
+
74
+ def test_custom_key_mapping
75
+ @client.expects(:get_file_data).with("image.png").returns("")
76
+ app_with(
77
+ :path => %r{^/assets/*},
78
+ :client => @client,
79
+ :mapper => lambda { |p| p.sub('/assets/', '') }
80
+ )
81
+
82
+ get '/assets/image.png'
83
+ end
84
+
42
85
  end
data/test/test_helper.rb CHANGED
@@ -4,3 +4,36 @@ require "rack"
4
4
  require "rack/mock"
5
5
  require "mocha"
6
6
  require "rack/mogilefs"
7
+
8
+ class MockMogileFsClient
9
+ def get_file_data(key)
10
+ "Mock Data for #{key}"
11
+ end
12
+ end
13
+
14
+ class Test::Unit::TestCase
15
+ def app_with(*args)
16
+ @app = Rack::Builder.new do
17
+ use Rack::Lint
18
+ use Rack::MogileFS, *args
19
+ use Rack::Lint
20
+ run lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
21
+ end
22
+ end
23
+
24
+ def get(path)
25
+ @response = Rack::MockRequest.new(@app).get(path)
26
+ end
27
+
28
+ def assert_body(body)
29
+ assert_equal body, @response.body
30
+ end
31
+
32
+ def assert_status(code)
33
+ assert_equal code, @response.status
34
+ end
35
+
36
+ def assert_content_type(content_type)
37
+ assert_equal content_type, @response.headers["Content-Type"]
38
+ end
39
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-mogilefs
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 2
10
+ version: 0.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ben Marini
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-08 00:00:00 -07:00
18
+ date: 2010-09-09 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -91,6 +91,7 @@ files:
91
91
  - lib/rack-mogilefs.rb
92
92
  - README.md
93
93
  - Rakefile
94
+ - HISTORY.md
94
95
  - test/mogilefs_test.rb
95
96
  - test/test_helper.rb
96
97
  has_rdoc: true