rack-grid-serve 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f5f4c81166fc96ed26ff25aa25d666fd3eb95f8
4
+ data.tar.gz: 942718fcfc8c8c49c89bf3c12393de2caadb6dfc
5
+ SHA512:
6
+ metadata.gz: d3d479c97d22a6f2ac53f264a167f39b7c6f7333241940f4cfacc031b75e47345278eb7cafe36d4a990539c136f5727c1c016a8c9f40163cdf8a2f324873d777
7
+ data.tar.gz: 6be2ba4449518d0886307ae5efa6a7c999537f72be046c40dfe0285982f071c5672596bb769cf592af92a0ba4ee4a54fc484ca3c22e4e4ca2473586be88080d0
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ .DS_STORE
2
+ *.swp
3
+ .ruby-version
4
+ pkg/
5
+ Gemfile.lock
6
+ *.gem
7
+ .bundle/
8
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2017 Mickael Riga
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
20
+
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ Rack Grid Serve
2
+ ===============
3
+
4
+ The purpose of `Rack::GridServe` is to provide an alternative to
5
+ [Rack::Gridfs]() which works with the `Mongo` ruby driver version 2.0
6
+ and above. This driver has a different API and while the `Rack::Gridfs`
7
+ team is working on it, it is not yet ready.
8
+
9
+ While `Rack::GridServe` can be used the same way, it is by no mean
10
+ as complete and well crafted as `Rack::Gridfs`. So I recommend that
11
+ you switch back when their next version is ready.
12
+
13
+ Until then, the function is the same, you can mount the middleware
14
+ in order to serve images which are hosted in the `GridFS` part
15
+ of a `Mongo` database.
16
+
17
+ How it works
18
+ ------------
19
+
20
+ Here is how you mount it in your `config.ru`:
21
+
22
+ ```ruby
23
+ require 'rack/grid_serve'
24
+ use Rack::GridServe, {
25
+ db: $db,
26
+ prefix: 'gridfs', # Path prefix, default is "gridfs"
27
+ cache_control: 'no-cache' # Default is "no-cache"
28
+ }
29
+ ```
30
+
31
+ These are the only options so far.
32
+
33
+ `Rack::GridServe` sets the `ETag` and `Last-Modified` response
34
+ headers and uses `Rack::ConditionalGet` to let the browser use
35
+ cached version of the files when possible.
36
+
37
+ Testing
38
+ -------
39
+
40
+ Run tests this way:
41
+
42
+ ```
43
+ bundle exec ruby -I lib test.rb
44
+ ```
45
+
@@ -0,0 +1,69 @@
1
+ require 'mongo'
2
+ require 'rack/request'
3
+ require 'rack/conditional_get'
4
+
5
+ class Rack::GridServe
6
+
7
+ VERSION = '0.0.1'
8
+
9
+ def initialize app, opts={}
10
+ @app = app
11
+ @db = opts[:db]
12
+ @prefix = opts[:prefix] || 'gridfs'
13
+ @cache_control = opts[:cache_control] || 'no-cache'
14
+ end
15
+
16
+ def call env
17
+ dup._call env
18
+ end
19
+
20
+ def _call env
21
+ req = Rack::Request.new env
22
+ if under_prefix? req
23
+ file = find_file req
24
+ if file.nil?
25
+ [404, {'Content-Type'=>'text/plain'}, 'Not Found']
26
+ else
27
+ last_modified = Time.at file.info.upload_date.to_i
28
+ headers = {
29
+ 'Content-Type' => file.info.content_type,
30
+ 'ETag' => file.info.md5,
31
+ 'Last-Modified' => last_modified.httpdate,
32
+ 'Cache-Control' => @cache_control
33
+ }
34
+ Rack::ConditionalGet.new(lambda {|cg_env|
35
+ [200, headers, [file.data]]
36
+ }).call(env)
37
+ end
38
+ else
39
+ @app.call env
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def under_prefix? req
46
+ req.path_info =~ %r|/#@prefix/(.*)|
47
+ end
48
+
49
+ def id_or_filename req
50
+ str = req.path_info.sub %r|/#@prefix/|, ''
51
+ if BSON::ObjectId.legal? str
52
+ BSON::ObjectId.from_string str
53
+ else
54
+ str
55
+ end
56
+ end
57
+
58
+ def find_file req
59
+ str = id_or_filename req
60
+ @db.fs.find_one({
61
+ '$or' => [
62
+ {_id: str},
63
+ {filename: str}
64
+ ]
65
+ })
66
+ end
67
+
68
+ end
69
+
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(__FILE__), 'lib/rack/grid_serve')
2
+
3
+ Gem::Specification.new do |s|
4
+
5
+ s.authors = ["Mickael Riga"]
6
+ s.email = ["mig@mypeplum.com"]
7
+ s.homepage = "https://github.com/mig-hub/rack-grid-serve"
8
+ s.licenses = ['MIT']
9
+
10
+ s.name = 'rack-grid-serve'
11
+ s.version = Rack::GridServe::VERSION
12
+ s.summary = "Rack middleware for serving files stored in MongoDB GridFS"
13
+ s.description = "Rack::GridServe is a Rack middleware for serving files stored in MongoDB GridFS. It is meant as a simple replacement for Rack::GridFS until it is ready for Mongo driver version 2.0 and above."
14
+
15
+ s.platform = Gem::Platform::RUBY
16
+ s.files = `git ls-files`.split("\n").sort
17
+ s.test_files = 'test.rb'
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_dependency('rack')
21
+ s.add_dependency('mongo', '~> 2.0')
22
+
23
+ s.add_development_dependency('minitest', '~> 5.8')
24
+ s.add_development_dependency('rack-test')
25
+
26
+ end
27
+
data/test.rb ADDED
@@ -0,0 +1,75 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'rack/grid_serve'
4
+ require 'rack/test'
5
+ require 'minitest/autorun'
6
+
7
+ class TestRackGridServe < MiniTest::Test
8
+
9
+ MONGO = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'rack-grid-serve-test')
10
+ DB = MONGO.database
11
+ DB.drop
12
+ FILE = Mongo::Grid::File.new('.cowabunga {}', :filename => 'tmnt.css', content_type: 'text/css')
13
+ FILE_ID = DB.fs.insert_one(FILE)
14
+
15
+ include Rack::Test::Methods
16
+
17
+ def app
18
+ Rack::GridServe.new(inner_app, db: DB)
19
+ end
20
+
21
+ def inner_app
22
+ lambda {|env|
23
+ [200, {'Content-Type'=>'text/plain'}, "Inner"]
24
+ }
25
+ end
26
+
27
+ def assert_file_found
28
+ assert_equal 200, last_response.status
29
+ assert_equal 13, last_response.body.size
30
+ assert_equal FILE.info.content_type, last_response.headers['Content-Type']
31
+ assert_equal FILE.info.md5, last_response.headers['ETag']
32
+ assert_equal Time.at(FILE.info.upload_date.to_i).httpdate, last_response.headers['Last-Modified']
33
+ assert_equal 'no-cache', last_response.headers['Cache-Control']
34
+ end
35
+
36
+ def test_finds_file_by_id
37
+ get "/gridfs/#{FILE_ID}"
38
+ assert_file_found
39
+ end
40
+
41
+ def test_finds_file_by_name
42
+ get '/gridfs/tmnt.css'
43
+ assert_file_found
44
+ end
45
+
46
+ def test_uses_conditional_get
47
+ get '/gridfs/tmnt.css', {}, {'HTTP_IF_NONE_MATCH'=>FILE.info.md5}
48
+ assert_equal 304, last_response.status
49
+ end
50
+
51
+ def test_not_found_if_filename_has_no_match
52
+ get '/gridfs/unexisting-id'
53
+ assert_equal 404, last_response.status
54
+ end
55
+
56
+ def test_pass_if_prefix_only
57
+ get '/gridfs'
58
+ assert_equal 200, last_response.status
59
+ assert_equal "Inner", last_response.body
60
+ end
61
+
62
+ def test_pass_if_root
63
+ get '/'
64
+ assert_equal 200, last_response.status
65
+ assert_equal "Inner", last_response.body
66
+ end
67
+
68
+ def test_pass_if_prefix_not_match
69
+ get '/wrong-prefix/1234'
70
+ assert_equal 200, last_response.status
71
+ assert_equal "Inner", last_response.body
72
+ end
73
+
74
+ end
75
+
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-grid-serve
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mickael Riga
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mongo
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Rack::GridServe is a Rack middleware for serving files stored in MongoDB
70
+ GridFS. It is meant as a simple replacement for Rack::GridFS until it is ready for
71
+ Mongo driver version 2.0 and above.
72
+ email:
73
+ - mig@mypeplum.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE
81
+ - README.md
82
+ - lib/rack/grid_serve.rb
83
+ - rack-grid-serve.gemspec
84
+ - test.rb
85
+ homepage: https://github.com/mig-hub/rack-grid-serve
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.4.5.1
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: Rack middleware for serving files stored in MongoDB GridFS
109
+ test_files:
110
+ - test.rb