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 +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
|