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 +8 -0
- data/README.md +22 -9
- data/Rakefile +9 -1
- data/lib/rack/mogilefs/endpoint.rb +10 -4
- data/test/mogilefs_test.rb +71 -28
- data/test/test_helper.rb +33 -0
- metadata +5 -4
data/HISTORY.md
ADDED
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
#
|
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{^/
|
17
|
+
use Rack::MogileFS, :path => %r{^/assets/*}
|
14
18
|
|
15
19
|
### Rails 3:
|
16
20
|
|
17
21
|
# (config/routes.rb)
|
18
|
-
match "/
|
22
|
+
match "/assets/*" => Rack::MogileFS::Endpoint.new
|
19
23
|
|
20
24
|
### Rails 2:
|
21
25
|
|
22
|
-
# (app/metal/
|
23
|
-
class
|
26
|
+
# (app/metal/mogilefs_metal.rb)
|
27
|
+
class MogilefsMetal
|
24
28
|
def self.call(env)
|
25
|
-
if env["PATH_INFO"] =~ %r{^/
|
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
|
-
|
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
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
data/test/mogilefs_test.rb
CHANGED
@@ -1,42 +1,85 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class TestMiddleWare < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
"Mock Data"
|
7
|
-
end
|
4
|
+
def setup
|
5
|
+
@client = MockMogileFsClient.new
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
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
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
35
|
-
|
48
|
+
def test_content_type_lookup
|
49
|
+
app_with :path => %r{^/assets/*}, :client => @client
|
50
|
+
get '/assets/asset.txt'
|
36
51
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.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-
|
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
|