rack-mogilefs 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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