rack-mogilefs 0.2.0 → 0.3.0

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ /coverage
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-mogilefs (0.3.0)
5
+ mogilefs-client (~> 2.1.0)
6
+ rack (~> 1.1.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ mocha (0.9.8)
12
+ rake
13
+ mogilefs-client (2.1.0)
14
+ rack (1.1.0)
15
+ rake (0.8.7)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ mocha
22
+ mogilefs-client (~> 2.1.0)
23
+ rack (~> 1.1.0)
24
+ rack-mogilefs!
data/HISTORY.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.3.0 (2010-12-30)
2
+
3
+ * Major refactoring of internals
4
+ * Codebase is now more modular, easier to extend and customize
5
+ * Add support for Cache-Control header
6
+ * Add debug flag to turn off built-in exception handling and make bugs easier
7
+ to find
8
+
1
9
  ## 0.2.0 (2010-11-29)
2
10
 
3
11
  * Add X-Reproxy-Url support
data/README.md CHANGED
@@ -4,33 +4,6 @@ If you are using Nginx you'll probably want to serve MogileFS files with
4
4
  the [MogileFS Module](http://www.grid.net.ru/nginx/mogilefs.en.html), but if
5
5
  you need a quick way to serve them out of a Rack app, this should help.
6
6
 
7
- ## Caveats ( serving files vs reproxying )
8
-
9
- Serving files through Ruby is slow. The preferred method is to set an
10
- X-Reproxy-Url header from your app and let the web server serve the file. For
11
- Nginx, you could have a config like this:
12
-
13
- location /reproxy {
14
- internal;
15
- set $reproxy $upstream_http_x_reproxy_url;
16
- proxy_pass $reproxy;
17
- proxy_hide_header Content-Type;
18
- }
19
-
20
- For Apache, there is [mod_reproxy](http://github.com/jamis/mod_reproxy)
21
-
22
- `Rack::MogileFS` will use this method if you pass a strategy option of `:reproxy`
23
-
24
- use Rack::MogileFS, :strategy => :reproxy
25
-
26
- `Rack::MogileFS` will look up the internal urls for the file, and set two
27
- headers to reproxy the request:
28
-
29
- X-Accel-Redirect: /reproxy
30
- X-Reproxy-Url: http://internal.ip/path/to/mogile/file.fid
31
-
32
- You'll have to make sure your web server knows how to handle this request.
33
-
34
7
  ## Getting Started:
35
8
 
36
9
  First install the gem:
@@ -39,10 +12,6 @@ First install the gem:
39
12
 
40
13
  There are a variety of ways to use it:
41
14
 
42
- ### Rack middleware
43
- # (config.ru)
44
- use Rack::MogileFS, :path => %r{^/assets/*}
45
-
46
15
  ### Rails 3:
47
16
 
48
17
  # (config/routes.rb)
@@ -61,6 +30,10 @@ There are a variety of ways to use it:
61
30
  end
62
31
  end
63
32
 
33
+ ### Rack middleware
34
+ # (config.ru)
35
+ use Rack::MogileFS, :path => %r{^/assets/*}
36
+
64
37
  ## File Lookup
65
38
 
66
39
  `Rack::MogileFS` uses the request path (`PATH_INFO`) for the MogileFS key. The
@@ -100,3 +73,35 @@ and initialize a MogileFS client like this:
100
73
  You can override this by passing in a MogileFS client of your own:
101
74
 
102
75
  Rack::MogileFS::Endpoint.new :client => MyMogileFSClient.new
76
+
77
+ ## Caveats ( serving files vs reproxying )
78
+
79
+ Serving files through Ruby can be slow. `Rack::MogileFS` will read the entire
80
+ file into memory before sending it downstream. If you have varnish/squid/a CDN
81
+ sitting in front of rails then this isn't so problematic.
82
+
83
+ The preferred method is to set an X-Reproxy-Url header from your app and let
84
+ the web server serve the file instead of `Rack::MogileFS`. For Nginx, you
85
+ could have a config like this:
86
+
87
+ location /reproxy {
88
+ internal;
89
+ set $reproxy $upstream_http_x_reproxy_url;
90
+ proxy_pass $reproxy;
91
+ proxy_hide_header Content-Type;
92
+ }
93
+
94
+ For Apache, there is [mod_reproxy](http://github.com/jamis/mod_reproxy)
95
+
96
+ `Rack::MogileFS` will use this method if you pass a strategy option of `:reproxy`
97
+
98
+ use Rack::MogileFS, :strategy => :reproxy
99
+
100
+ `Rack::MogileFS` will look up the internal urls for the file, and set two
101
+ headers to reproxy the request:
102
+
103
+ X-Accel-Redirect: /reproxy
104
+ X-Reproxy-Url: http://internal.ip/path/to/mogile/file.fid
105
+
106
+ You'll have to make sure your web server knows how to handle this request.
107
+
data/Rakefile CHANGED
@@ -1,3 +1,6 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
1
4
  require 'rake/clean'
2
5
  require 'rake/testtask'
3
6
 
@@ -17,4 +20,4 @@ task :coverage do
17
20
  rm_f "coverage.data"
18
21
  system "rcov -x /Users -Ilib:test test/*_test.rb"
19
22
  system "open coverage/index.html" if PLATFORM['darwin']
20
- end
23
+ end
data/lib/rack/mogilefs.rb CHANGED
@@ -5,6 +5,7 @@ require 'rack/utils'
5
5
  module Rack
6
6
  class MogileFS
7
7
  autoload :Endpoint, "rack/mogilefs/endpoint"
8
+ autoload :Version, "rack/mogilefs/version"
8
9
 
9
10
  def initialize(app, options={})
10
11
  @app, @options = app, options
@@ -1,82 +1,40 @@
1
+ require 'rack/mogilefs/endpoint/base'
2
+ require 'rack/mogilefs/endpoint/caching'
3
+ require 'rack/mogilefs/endpoint/client'
4
+ require 'rack/mogilefs/endpoint/mapper'
5
+ require 'rack/mogilefs/endpoint/reproxy'
6
+ require 'rack/mogilefs/endpoint/rescues'
7
+
1
8
  module Rack
2
9
  class MogileFS
3
10
  class Endpoint
4
11
 
5
- def initialize(options={})
6
- @options = {
7
- :client => nil,
8
- :mapper => nil,
9
- :strategy => :serve,
10
- :default_content_type => "image/png"
11
- }.merge(options)
12
-
13
- @options[:client] ||= default_client
14
- end
15
-
16
- def call(env)
17
- path = key_for_path(env['PATH_INFO'].dup)
12
+ class File
13
+ attr_accessor :path, :data
18
14
 
19
- if @options[:strategy] == :reproxy
20
- reproxy(path)
21
- else
22
- serve_file(path)
15
+ def initialize(path, data)
16
+ @path, @data = path, data
23
17
  end
24
18
 
25
- rescue ::MogileFS::Backend::UnknownKeyError => e
26
- [ 404, { "Content-Type" => "text/html" }, [e.message] ]
27
- rescue ::MogileFS::UnreachableBackendError => e
28
- [ 503, { "Content-Type" => "text/html" }, [e.message] ]
29
- rescue ::MogileFS::Error => e
30
- [ 500, { "Content-Type" => "text/html" }, [e.message] ]
31
- end
32
-
33
- protected
34
-
35
- def reproxy(path)
36
- paths = client.get_paths(path)
37
-
38
- [ 200, {
39
- "Content-Type" => content_type(path),
40
- "X-Accel-Redirect" => "/reproxy",
41
- "X-Reproxy-Url" => paths.join(" ")
42
- }, [] ]
43
- end
44
-
45
- def serve_file(path)
46
- data = client.get_file_data(path)
47
- size = Utils.bytesize(data).to_s
48
-
49
- [ 200, {
50
- "Content-Type" => content_type(path),
51
- "Content-Length" => size
52
- }, [data] ]
53
- end
54
-
55
- def key_for_path(path)
56
- @options[:mapper].respond_to?(:call) ? @options[:mapper].call(path) : path
57
- end
58
-
59
- def content_type(path)
60
- Mime.mime_type(::File.extname(path), @options[:default_content_type])
61
- end
62
-
63
- def client
64
- @options[:client]
65
- end
19
+ def extname
20
+ ::File.extname(@path)
21
+ end
66
22
 
67
- def default_client
68
- ::MogileFS::MogileFS.new(config)
69
- end
23
+ def length
24
+ Utils.bytesize(@data).to_s
25
+ end
70
26
 
71
- def config
72
- if defined?(Rails)
73
- yml = YAML.load_file( Rails.root.join("config/mogilefs.yml") )
74
- yml[Rails.env]["connection"].symbolize_keys
75
- else
76
- { :domain => "default", :hosts => ["127.0.0.1:7001"] }
27
+ def content_type(default=nil)
28
+ Mime.mime_type(extname, default)
77
29
  end
78
30
  end
79
31
 
32
+ include Base
33
+ include Client
34
+ include Caching
35
+ include Mapper
36
+ include Reproxy
37
+ include Rescues
80
38
  end
81
39
  end
82
40
  end
@@ -0,0 +1,47 @@
1
+ module Rack
2
+ class MogileFS
3
+ class Endpoint
4
+
5
+ # This contains the base functionality for serving a MogileFS file. Most
6
+ # of the useful stuff is layered on top the base class in other modules
7
+ module Base
8
+ def initialize(options={})
9
+ @options = {
10
+ :default_content_type => "image/png"
11
+ }.merge(options)
12
+ end
13
+
14
+ def call(env)
15
+ path = key_for_path( env['PATH_INFO'].dup )
16
+ serve_file(path)
17
+ end
18
+
19
+ protected
20
+
21
+ def serve_file(path)
22
+ data = client.get_file_data(path)
23
+ file = File.new(path, data)
24
+
25
+ [ 200, headers(file), [data] ]
26
+ end
27
+
28
+ def client
29
+ @options[:client]
30
+ end
31
+
32
+ def key_for_path(path)
33
+ path
34
+ end
35
+
36
+ def headers(file)
37
+ {
38
+ "Content-Type" => file.content_type(@options[:default_content_type]),
39
+ "Content-Length" => file.length
40
+ }
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ module Rack
2
+ class MogileFS
3
+ class Endpoint
4
+
5
+ # Adds support for expires headers. You can specify a number or a proc
6
+ # that will recieve (path, ext, mime) as arguements. You should return
7
+ # the number of seconds to cache.
8
+ module Caching
9
+ def initialize(*)
10
+ super
11
+ @options[:expires] ||= false
12
+ end
13
+
14
+ def headers(file)
15
+ super.merge( cache_control_header(file) )
16
+ end
17
+
18
+ private
19
+
20
+ def cache_control_header(file)
21
+ if @options[:expires]
22
+ { "Cache-Control" => "max-age=#{max_age(file)}, public" }
23
+ else
24
+ {}
25
+ end
26
+ end
27
+
28
+ def max_age(file)
29
+ if @options[:expires].respond_to?(:call)
30
+ @options[:expires].call(file.path, file.extname, file.content_type)
31
+ else
32
+ @options[:expires]
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,41 @@
1
+ module Rack
2
+ class MogileFS
3
+ class Endpoint
4
+
5
+ # Provides a default client if one is not passed in a a param. It is
6
+ # recommended to use the default client if you can
7
+ module Client
8
+ def initialize(*)
9
+ super
10
+ @options[:client] ||= default_client
11
+ end
12
+
13
+ def default_client
14
+ ::MogileFS::MogileFS.new(config)
15
+ end
16
+
17
+ # If `Rack::MogileFS` detects it is inside a Rails app, it will look
18
+ # for a yaml config in `config/mogilefs.yml` that looks like this:
19
+ #
20
+ # development:
21
+ # connection:
22
+ # domain: "development.myapp.com"
23
+ # hosts:
24
+ # - 127.0.0.1:7001
25
+ # - 127.0.0.1:7001
26
+ # class: "file"
27
+ # staging:
28
+ # ...
29
+ def config
30
+ if defined?(Rails)
31
+ yml = YAML.load_file( Rails.root.join("config/mogilefs.yml") )
32
+ yml[Rails.env]["connection"].symbolize_keys
33
+ else
34
+ { :domain => "default", :hosts => ["127.0.0.1:7001"] }
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ module Rack
2
+ class MogileFS
3
+ class Endpoint
4
+
5
+ # Adds ability to pass in a custom mapper to map PATH_INFO to a
6
+ # MogileFS key. By default it is assumed that the path is the same as
7
+ # the key. For example your keys will look like this:
8
+ #
9
+ # "/assets/images/myimage.gif"
10
+ #
11
+ # Create a custom mapper like this:
12
+ #
13
+ # Rack::MogileFS::Endpoint.new(
14
+ # :mapper => lambda { |path| "/namespace/" + path }
15
+ # )
16
+ module Mapper
17
+ def key_for_path(path)
18
+ @options[:mapper].respond_to?(:call) ?
19
+ @options[:mapper].call(path) : super
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ module Rack
2
+ class MogileFS
3
+ class Endpoint
4
+
5
+ # Adds reproxy support. To activate:
6
+ #
7
+ # Rack::MogileFS::Endpoint.new :strategy => :reproxy
8
+ module Reproxy
9
+ def initialize(*)
10
+ super
11
+ @options[:strategy] ||= :serve
12
+ end
13
+
14
+ def serve_file(path)
15
+ if @options[:strategy] == :reproxy
16
+ reproxy(path)
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def reproxy(path)
23
+ paths = client.get_paths(path)
24
+ file = File.new(path, nil)
25
+
26
+ [ 200, {
27
+ "Content-Type" => file.content_type,
28
+ "X-Accel-Redirect" => "/reproxy",
29
+ "X-Reproxy-Url" => paths.join(" ")
30
+ }, [] ]
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ module Rack
2
+ class MogileFS
3
+ class Endpoint
4
+
5
+ # Catches some potential MogileFS exceptions and will return sensible
6
+ # HTTP status codes. You can disable with:
7
+ #
8
+ # Rack::MogileFS::Endpoint.new :debug => true
9
+ module Rescues
10
+ def initialize(*)
11
+ super
12
+ @options[:debug] ||= false
13
+ end
14
+
15
+ def call(env)
16
+ if @options[:debug]
17
+ super
18
+ else
19
+ with_rescues { super }
20
+ end
21
+ end
22
+
23
+ def with_rescues
24
+ yield
25
+ rescue ::MogileFS::Backend::UnknownKeyError => e
26
+ [ 404, { "Content-Type" => "text/html" }, [e.message] ]
27
+ rescue ::MogileFS::UnreachableBackendError => e
28
+ [ 503, { "Content-Type" => "text/html" }, [e.message] ]
29
+ rescue ::MogileFS::Error => e
30
+ [ 500, { "Content-Type" => "text/html" }, [e.message] ]
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class MogileFS
3
+ VERSION = "0.3.0"
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rack/mogilefs/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rack-mogilefs"
7
+ s.version = Rack::MogileFS::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+
10
+ s.date = "2010-09-10"
11
+ s.summary = "A rack middleware and/or endpoint to serve up files from MogileFS"
12
+ s.email = "bmarini@gmail.com"
13
+ s.homepage = "http://github.com/bmarini/rack-mogilefs"
14
+ s.description = "A rack middleware and/or endpoint to serve up files from MogileFS"
15
+ s.authors = ["Ben Marini"]
16
+
17
+ s.rubyforge_project = "rack-mogilefs"
18
+
19
+ s.add_dependency "mogilefs-client", "~> 2.1.0"
20
+ s.add_dependency "rack", "~> 1.1.0"
21
+ s.add_development_dependency "mocha"
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ["lib"]
27
+ end
data/release.rb ADDED
@@ -0,0 +1,6 @@
1
+ version = ARGV.pop
2
+
3
+ puts "Building and pushing Rack::MogileFS..."
4
+ `gem build rack-mogilefs.gemspec`
5
+ `gem push rack-mogilefs-#{version}.gem`
6
+ `rm rack-mogilefs-#{version}.gem`
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ class TestCaching < Test::Unit::TestCase
4
+ def setup
5
+ @client = MockMogileFsClient.new
6
+ end
7
+
8
+ def test_expires_with_int
9
+ @client.expects(:get_file_data).with("/assets/image.png").returns("")
10
+
11
+ app_with(
12
+ :path => %r{^/assets/*},
13
+ :client => @client,
14
+ :expires => 300
15
+ )
16
+
17
+ get '/assets/image.png'
18
+ assert_status 200
19
+ assert_cache_control "max-age=300, public"
20
+ end
21
+
22
+ def test_expires_with_lambda
23
+ @client.expects(:get_file_data).with("/assets/image.jpg").returns("")
24
+
25
+ app_with(
26
+ :path => %r{^/assets/*},
27
+ :client => @client,
28
+ :expires => lambda { |path, ext, mime|
29
+ mime == "image/jpeg" ? 600 : 300
30
+ }
31
+ )
32
+
33
+ get '/assets/image.jpg'
34
+ assert_status 200
35
+ assert_cache_control "max-age=600, public"
36
+ end
37
+
38
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ class TestContentType < Test::Unit::TestCase
4
+ def setup
5
+ @client = MockMogileFsClient.new
6
+ end
7
+
8
+ def test_content_type_lookup
9
+ app_with :path => %r{^/assets/*}, :client => @client
10
+ get '/assets/asset.txt'
11
+
12
+ assert_status 200
13
+ assert_content_type "text/plain"
14
+
15
+ get '/assets/asset.png'
16
+
17
+ assert_status 200
18
+ assert_content_type "image/png"
19
+
20
+ get '/assets/asset.xml'
21
+
22
+ assert_status 200
23
+ assert_content_type "application/xml"
24
+ end
25
+
26
+ def test_default_content_type
27
+ app_with :path => %r{^/assets/*}, :client => @client
28
+ get '/assets/asset.xxx'
29
+
30
+ assert_status 200
31
+ assert_content_type "image/png"
32
+ end
33
+
34
+ end
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ class TestMapper < Test::Unit::TestCase
4
+ def setup
5
+ @client = MockMogileFsClient.new
6
+ end
7
+
8
+ def test_custom_key_mapping
9
+ @client.expects(:get_file_data).with("image.png").returns("")
10
+ app_with(
11
+ :path => %r{^/assets/*},
12
+ :client => @client,
13
+ :mapper => lambda { |p| p.sub('/assets/', '') }
14
+ )
15
+
16
+ get '/assets/image.png'
17
+ end
18
+
19
+ end
@@ -12,32 +12,6 @@ class TestMiddleWare < Test::Unit::TestCase
12
12
  assert_body "Hello, World!"
13
13
  end
14
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'
28
-
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
39
- end
40
-
41
15
  def test_middleware_with_mock_mogile_client
42
16
  app_with :path => %r{^/assets/*}, :client => @client
43
17
  get '/assets/asset.txt'
@@ -45,41 +19,4 @@ class TestMiddleWare < Test::Unit::TestCase
45
19
  assert_body "Mock Data for /assets/asset.txt"
46
20
  end
47
21
 
48
- def test_content_type_lookup
49
- app_with :path => %r{^/assets/*}, :client => @client
50
- get '/assets/asset.txt'
51
-
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"
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
-
85
22
  end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ class TestReproxy < Test::Unit::TestCase
4
+ def setup
5
+ @client = MockMogileFsClient.new
6
+ end
7
+
8
+ def test_reproxy
9
+ @client.expects(:get_paths).with("/assets/image.png").returns( %w(/path/1.png /path/2.png) )
10
+
11
+ app_with(
12
+ :path => %r{^/assets/*},
13
+ :client => @client,
14
+ :strategy => :reproxy
15
+ )
16
+
17
+ get '/assets/image.png'
18
+ assert_status 200
19
+ assert_content_type "image/png"
20
+ assert_equal_header "/reproxy", "X-Accel-Redirect"
21
+ assert_equal_header "/path/1.png /path/2.png", "X-Reproxy-Url"
22
+ end
23
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ class TestRescues < Test::Unit::TestCase
4
+ def setup
5
+ @client = MockMogileFsClient.new
6
+ end
7
+
8
+ def test_debug_mode
9
+ app_with :path => %r{^/assets/*}, :debug => true
10
+ assert_raises(MogileFS::UnreachableBackendError) do
11
+ get '/assets/unreachable.txt'
12
+ end
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'
28
+
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
39
+ end
40
+
41
+ end
data/test/test_helper.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require "rubygems"
2
+ require "bundler/setup"
3
+
2
4
  require "test/unit"
3
5
  require "rack"
4
6
  require "rack/mock"
@@ -34,6 +36,14 @@ class Test::Unit::TestCase
34
36
  end
35
37
 
36
38
  def assert_content_type(content_type)
37
- assert_equal content_type, @response.headers["Content-Type"]
39
+ assert_equal_header content_type, "Content-Type"
40
+ end
41
+
42
+ def assert_cache_control(cache_control)
43
+ assert_equal_header cache_control, "Cache-Control"
44
+ end
45
+
46
+ def assert_equal_header(expected, header)
47
+ assert_equal expected, @response.headers[header]
38
48
  end
39
49
  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: 23
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ben Marini
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ">="
43
+ - - ~>
44
44
  - !ruby/object:Gem::Version
45
45
  hash: 19
46
46
  segments:
@@ -51,7 +51,7 @@ dependencies:
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
- name: rack
54
+ name: mocha
55
55
  prerelease: false
56
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
57
  none: false
@@ -64,20 +64,6 @@ dependencies:
64
64
  version: "0"
65
65
  type: :development
66
66
  version_requirements: *id003
67
- - !ruby/object:Gem::Dependency
68
- name: mocha
69
- prerelease: false
70
- requirement: &id004 !ruby/object:Gem::Requirement
71
- none: false
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- hash: 3
76
- segments:
77
- - 0
78
- version: "0"
79
- type: :development
80
- version_requirements: *id004
81
67
  description: A rack middleware and/or endpoint to serve up files from MogileFS
82
68
  email: bmarini@gmail.com
83
69
  executables: []
@@ -87,13 +73,30 @@ extensions: []
87
73
  extra_rdoc_files: []
88
74
 
89
75
  files:
90
- - lib/rack/mogilefs/endpoint.rb
91
- - lib/rack/mogilefs.rb
92
- - lib/rack-mogilefs.rb
76
+ - .gitignore
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - HISTORY.md
93
80
  - README.md
94
81
  - Rakefile
95
- - HISTORY.md
82
+ - lib/rack-mogilefs.rb
83
+ - lib/rack/mogilefs.rb
84
+ - lib/rack/mogilefs/endpoint.rb
85
+ - lib/rack/mogilefs/endpoint/base.rb
86
+ - lib/rack/mogilefs/endpoint/caching.rb
87
+ - lib/rack/mogilefs/endpoint/client.rb
88
+ - lib/rack/mogilefs/endpoint/mapper.rb
89
+ - lib/rack/mogilefs/endpoint/reproxy.rb
90
+ - lib/rack/mogilefs/endpoint/rescues.rb
91
+ - lib/rack/mogilefs/version.rb
92
+ - rack-mogilefs.gemspec
93
+ - release.rb
94
+ - test/caching_test.rb
95
+ - test/content_type_test.rb
96
+ - test/mapper_test.rb
96
97
  - test/mogilefs_test.rb
98
+ - test/reproxy_test.rb
99
+ - test/rescues_test.rb
97
100
  - test/test_helper.rb
98
101
  has_rdoc: true
99
102
  homepage: http://github.com/bmarini/rack-mogilefs
@@ -124,11 +127,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
127
  version: "0"
125
128
  requirements: []
126
129
 
127
- rubyforge_project:
130
+ rubyforge_project: rack-mogilefs
128
131
  rubygems_version: 1.3.7
129
132
  signing_key:
130
133
  specification_version: 3
131
134
  summary: A rack middleware and/or endpoint to serve up files from MogileFS
132
135
  test_files:
136
+ - test/caching_test.rb
137
+ - test/content_type_test.rb
138
+ - test/mapper_test.rb
133
139
  - test/mogilefs_test.rb
140
+ - test/reproxy_test.rb
141
+ - test/rescues_test.rb
134
142
  - test/test_helper.rb