rack_resize 0.1.0 → 0.1.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 +4 -4
- data/.github/workflows/test.yml +29 -0
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/README.md +106 -4
- data/Rakefile +9 -0
- data/config.ru +7 -1
- data/lib/rack_resize/configuration.rb +10 -6
- data/lib/rack_resize/rack_app.rb +6 -7
- data/rack_resize.gemspec +1 -1
- data/samples/image_1.jpeg +0 -0
- data/samples/image_2.jpeg +0 -0
- data/samples/image_3.jpeg +0 -0
- data/samples/image_4.jpeg +0 -0
- data/samples/index.html +34 -0
- data/test/rack_app_test.rb +146 -0
- data/test/test_helper.rb +5 -0
- metadata +11 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '09480d8110a0fd174b70144ea5df62c1146f2c16399cd9e173a0638d5cf818b7'
|
|
4
|
+
data.tar.gz: 24f936049e0bed57e1ff90c49f588d48480700adae2b2b6829685df011ecb89f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: be9835971015420520f16a1332a0ac5664668150f06d6f577148803a7a299142c9edffdd9e33581d64b76b0a0aa8fb2cec9cbd2ce8524cdfa45f966721177610
|
|
7
|
+
data.tar.gz: b48663c5733f65c3e55fff126df2a31ff99f64bc0fceccd3c9fbc10261ea0ed5acfd99e7705333e24486ef6464d776df2d7ab9b92c5d8ab198d8646b1ae0d224
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
ruby: ['3.3', '3.4', '4.0']
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install package
|
|
20
|
+
run: |
|
|
21
|
+
sudo apt-get update
|
|
22
|
+
sudo apt-get install -y libvips42 imagemagick libimlib2 libimlib2-dev
|
|
23
|
+
|
|
24
|
+
- uses: ruby/setup-ruby@v1
|
|
25
|
+
with:
|
|
26
|
+
ruby-version: ${{ matrix.ruby }}
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
|
|
29
|
+
- run: bundle exec rake test
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,108 @@
|
|
|
1
|
+
[](https://badge.fury.io/rb/rack_resize)
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
RESIZE IMAGE sips samples/big.jpg - {:width=>"150"} - 0.121s
|
|
4
|
-
RESIZE IMAGE vips samples/big.jpg - {:width=>"150"} - 0.116s
|
|
3
|
+
Designed to be local simulation of CDN's resize feature
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
How to use with Rails
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
group :development do
|
|
9
|
+
gem "rack_resize", require: "rack_resize/rails_autoload"
|
|
10
|
+
end
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
How to use with Rack
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
use RackResize::RackApp, processor: :imlib2, assets_folder: "samples"
|
|
17
|
+
use Rack::Static, urls: [""], root: "samples", index: "index.html" # optional
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### URL Formats:
|
|
21
|
+
|
|
22
|
+
Cloudflare format: (can be used with helpers from `carrierwave-cloudflare` gem)
|
|
23
|
+
```
|
|
24
|
+
/cdn-cgi/image/width=426,format=auto/assets/pets/dog.jpg
|
|
25
|
+
```
|
|
26
|
+
Fastly and bunny.net: (tbd)
|
|
27
|
+
```
|
|
28
|
+
/assets/pets/dog.jpg?width=300
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Configuration:
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
RackResize.configure do |config|
|
|
35
|
+
config.assets_folder = Rails.root.join('app', 'assets', 'images')
|
|
36
|
+
config.processor = :sips / :vips / :mini_magick / :imlib2
|
|
37
|
+
config.default_quality = 95
|
|
38
|
+
config.save_resized = false
|
|
39
|
+
config.cache_folder = Rails.root.join('tmp', 'rack_resize_cache') # used if save_resized enabled
|
|
40
|
+
config.http_cache_max_age = 86400
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Supported Processing Backends:
|
|
45
|
+
|
|
46
|
+
<table>
|
|
47
|
+
<tr>
|
|
48
|
+
<th>libaray</th>
|
|
49
|
+
<th>dependency</th>
|
|
50
|
+
<th>config</th>
|
|
51
|
+
</tr>
|
|
52
|
+
<tr>
|
|
53
|
+
<td>mini_magick</td>
|
|
54
|
+
<td>
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
gem "image_processing"
|
|
58
|
+
gem "mini_magick"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
</td>
|
|
62
|
+
<td>
|
|
63
|
+
|
|
64
|
+
`processor: :mini_magick`
|
|
65
|
+
|
|
66
|
+
</td>
|
|
67
|
+
</tr>
|
|
68
|
+
<tr>
|
|
69
|
+
<td>vips</td>
|
|
70
|
+
<td>
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
gem "image_processing"
|
|
74
|
+
gem "ruby-vips"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
</td>
|
|
78
|
+
<td>
|
|
79
|
+
|
|
80
|
+
`processor: :vips`
|
|
81
|
+
|
|
82
|
+
</td>
|
|
83
|
+
</tr>
|
|
84
|
+
<tr>
|
|
85
|
+
<td>sips (MacOS only)</td>
|
|
86
|
+
<td>none</td>
|
|
87
|
+
<td>
|
|
88
|
+
|
|
89
|
+
`processor: :sips`
|
|
90
|
+
|
|
91
|
+
</td>
|
|
92
|
+
</tr>
|
|
93
|
+
<tr>
|
|
94
|
+
<td>imlib2</td>
|
|
95
|
+
<td>
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
gem "rszr"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
</td>
|
|
102
|
+
<td>
|
|
103
|
+
|
|
104
|
+
`processor: :imlib2`
|
|
105
|
+
|
|
106
|
+
</td>
|
|
107
|
+
</tr>
|
|
108
|
+
</table>
|
data/Rakefile
ADDED
data/config.ru
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
#
|
|
2
|
+
# usage:
|
|
3
|
+
# gem install rackup
|
|
4
|
+
# rackup
|
|
5
|
+
#
|
|
6
|
+
|
|
1
7
|
require_relative "lib/rack_resize"
|
|
2
8
|
require "rack/static"
|
|
3
9
|
|
|
4
|
-
use RackResize::RackApp, processor: :imlib2, assets_folder: "samples"
|
|
10
|
+
use RackResize::RackApp, processor: :imlib2, assets_folder: "samples"
|
|
5
11
|
|
|
6
12
|
use Rack::Static, urls: [""], root: "samples", index: "index.html"
|
|
7
13
|
|
|
@@ -4,20 +4,24 @@ class RackResize::Configuration
|
|
|
4
4
|
PROCESSORS = %i[sips vips mini_magick imlib2].freeze
|
|
5
5
|
|
|
6
6
|
attr_reader :processor
|
|
7
|
-
attr_accessor :save_resized, :default_quality, :cache_folder, :assets_folder
|
|
7
|
+
attr_accessor :save_resized, :default_quality, :cache_folder, :assets_folder, :http_cache_max_age
|
|
8
8
|
|
|
9
9
|
alias_method :save_resized?, :save_resized
|
|
10
10
|
|
|
11
11
|
def initialize(options = {})
|
|
12
|
-
@processor
|
|
13
|
-
@save_resized
|
|
14
|
-
@default_quality
|
|
15
|
-
@cache_folder
|
|
16
|
-
@assets_folder
|
|
12
|
+
@processor = options[:processor] || RUBY_PLATFORM.include?('darwin') ? :sips : :mini_magick
|
|
13
|
+
@save_resized = options.key?(:save_resized) ? options[:save_resized] : false
|
|
14
|
+
@default_quality = options[:default_quality] || 95
|
|
15
|
+
@cache_folder = options[:cache_folder]
|
|
16
|
+
@assets_folder = options[:assets_folder] ? Pathname.new(options[:assets_folder]) : nil
|
|
17
|
+
@http_cache_max_age = options[:http_cache_max_age] || 86400 # 1 day
|
|
17
18
|
|
|
18
19
|
if defined?(Rails)
|
|
19
20
|
@cache_folder ||= Rails.root.join('tmp', 'rack_resize_cache')
|
|
20
21
|
@assets_folder ||= Rails.root.join('app', 'assets', 'images')
|
|
22
|
+
unless options.key?(:save_resized)
|
|
23
|
+
@save_resized = true
|
|
24
|
+
end
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
if options[:processor]
|
data/lib/rack_resize/rack_app.rb
CHANGED
|
@@ -13,20 +13,20 @@ class RackResize::RackApp
|
|
|
13
13
|
|
|
14
14
|
@config = options == {} ? RackResize.config : RackResize::Configuration.new(options)
|
|
15
15
|
@processing = RackResize::Processing.new(config: @config)
|
|
16
|
-
@
|
|
16
|
+
@cf_path_prefix = options[:cf_path_prefix] || "/cdn-cgi/image"
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def call(env)
|
|
20
|
-
# process string like this
|
|
21
|
-
# /cdn-cgi/image/width=426,format=auto/assets/templates/vancouver-27c47f55.jpg
|
|
22
|
-
|
|
23
20
|
request = Rack::Request.new(env)
|
|
24
21
|
fullpath = request.path_info
|
|
25
22
|
|
|
26
|
-
unless fullpath.start_with?(@
|
|
23
|
+
unless fullpath.start_with?(@cf_path_prefix)
|
|
27
24
|
return @app.call(env)
|
|
28
25
|
end
|
|
29
26
|
|
|
27
|
+
# process string like this
|
|
28
|
+
# /cdn-cgi/image/width=426,format=auto/assets/templates/vancouver-27c47f55.jpg
|
|
29
|
+
|
|
30
30
|
fullpath = fullpath.delete_prefix("/cdn-cgi").delete_prefix("/image").delete_prefix("/")
|
|
31
31
|
file_path_match = fullpath.match(%r{(?<params>[^\/]+)(?<file>\/.+?)(-[\da-f]{8})?(?<ext>\.\w{2,})$})
|
|
32
32
|
|
|
@@ -58,7 +58,6 @@ class RackResize::RackApp
|
|
|
58
58
|
|
|
59
59
|
def send_file(asset_file:, file_content: nil)
|
|
60
60
|
content_type = Rack::Mime.mime_type(File.extname(asset_file), "application/octet-stream")
|
|
61
|
-
# file = file_path ? File.open(file_path, "rb") : StringIO.new(file_content)
|
|
62
61
|
|
|
63
62
|
[
|
|
64
63
|
200,
|
|
@@ -66,7 +65,7 @@ class RackResize::RackApp
|
|
|
66
65
|
"content-type" => content_type,
|
|
67
66
|
"content-length" => file_content.size.to_s,
|
|
68
67
|
"content-disposition" => "inline",
|
|
69
|
-
"cache-control" => "max-age
|
|
68
|
+
"cache-control" => "max-age=#{config.http_cache_max_age}" # 1 day
|
|
70
69
|
},
|
|
71
70
|
file_content
|
|
72
71
|
]
|
data/rack_resize.gemspec
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/samples/index.html
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
height 150: <br>
|
|
5
|
+
<img src="/cdn-cgi/image/height=150/samples/image_1.jpeg"/>
|
|
6
|
+
<img src="/cdn-cgi/image/height=150/samples/image_2.jpeg"/>
|
|
7
|
+
<img src="/cdn-cgi/image/height=150/samples/image_3.jpeg"/>
|
|
8
|
+
<img src="/cdn-cgi/image/height=150/samples/image_4.jpeg"/>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p>
|
|
12
|
+
width 150: <br>
|
|
13
|
+
<img src="/cdn-cgi/image/width=150/samples/image_1.jpeg"/>
|
|
14
|
+
<img src="/cdn-cgi/image/width=150/samples/image_2.jpeg"/>
|
|
15
|
+
<img src="/cdn-cgi/image/width=150/samples/image_3.jpeg"/>
|
|
16
|
+
<img src="/cdn-cgi/image/width=150/samples/image_4.jpeg"/>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<p>
|
|
20
|
+
width 50: <br>
|
|
21
|
+
<img src="/cdn-cgi/image/width=50/samples/image_1.jpeg"/>
|
|
22
|
+
<img src="/cdn-cgi/image/width=50/samples/image_2.jpeg"/>
|
|
23
|
+
<img src="/cdn-cgi/image/width=50/samples/image_3.jpeg"/>
|
|
24
|
+
<img src="/cdn-cgi/image/width=50/samples/image_4.jpeg"/>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<p>
|
|
28
|
+
originals: <br>
|
|
29
|
+
<img src="image_1.jpeg"/>
|
|
30
|
+
<img src="image_2.jpeg"/>
|
|
31
|
+
<img src="image_3.jpeg"/>
|
|
32
|
+
<img src="image_4.jpeg"/>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'test_helper'
|
|
4
|
+
|
|
5
|
+
class RackAppTest < Minitest::Test
|
|
6
|
+
UPSTREAM = ->(env) { [200, { 'content-type' => 'text/plain' }, ['upstream']] }
|
|
7
|
+
|
|
8
|
+
def setup
|
|
9
|
+
@tmpdir = Dir.mktmpdir('rack_resize_test')
|
|
10
|
+
File.write(File.join(@tmpdir, 'photo.jpg'), 'fake jpeg content')
|
|
11
|
+
|
|
12
|
+
@app = RackResize::RackApp.new(
|
|
13
|
+
UPSTREAM,
|
|
14
|
+
assets_folder: @tmpdir,
|
|
15
|
+
processor: :sips,
|
|
16
|
+
save_resized: false
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
fake_processing = Object.new
|
|
20
|
+
def fake_processing.process!(**) = StringIO.new('processed image data')
|
|
21
|
+
@app.instance_variable_set(:@processing, fake_processing)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def teardown
|
|
25
|
+
FileUtils.rm_rf(@tmpdir)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# --- error_resp ---
|
|
29
|
+
|
|
30
|
+
def test_error_resp_default_status
|
|
31
|
+
status, headers, body = @app.error_resp('oops')
|
|
32
|
+
assert_equal 404, status
|
|
33
|
+
assert_equal({}, headers)
|
|
34
|
+
assert_equal ['oops'], body
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_error_resp_custom_status
|
|
38
|
+
status, _, body = @app.error_resp('bad input', http_code: 422)
|
|
39
|
+
assert_equal 422, status
|
|
40
|
+
assert_equal ['bad input'], body
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# --- send_file ---
|
|
44
|
+
|
|
45
|
+
def test_send_file_returns_200_with_headers
|
|
46
|
+
asset_file = Pathname.new(File.join(@tmpdir, 'photo.jpg'))
|
|
47
|
+
content = StringIO.new('hello')
|
|
48
|
+
status, headers, _ = @app.send_file(asset_file:, file_content: content)
|
|
49
|
+
|
|
50
|
+
assert_equal 200, status
|
|
51
|
+
assert_equal 'image/jpeg', headers['content-type']
|
|
52
|
+
assert_equal '5', headers['content-length']
|
|
53
|
+
assert_equal 'inline', headers['content-disposition']
|
|
54
|
+
assert_match(/\d+/, headers['cache-control'])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# --- pass-through for non-cdn-cgi paths ---
|
|
58
|
+
|
|
59
|
+
def test_passes_through_unrelated_paths
|
|
60
|
+
env = Rack::MockRequest.env_for('/foo/bar.jpg')
|
|
61
|
+
status, _, body = @app.call(env)
|
|
62
|
+
assert_equal 200, status
|
|
63
|
+
assert_equal ['upstream'], body
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_passes_through_root_path
|
|
67
|
+
env = Rack::MockRequest.env_for('/')
|
|
68
|
+
_, _, body = @app.call(env)
|
|
69
|
+
assert_equal ['upstream'], body
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# --- path parsing errors ---
|
|
73
|
+
|
|
74
|
+
def test_returns_404_for_unparseable_path
|
|
75
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/bad-path-no-extension')
|
|
76
|
+
status, _, body = @app.call(env)
|
|
77
|
+
assert_equal 404, status
|
|
78
|
+
assert_equal ["can't parse file path"], body
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_returns_404_for_path_traversal
|
|
82
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/width=100/assets/../etc/photo.jpg')
|
|
83
|
+
status, _, body = @app.call(env)
|
|
84
|
+
assert_equal 404, status
|
|
85
|
+
assert_equal ['.. is not allowed in image path'], body
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_returns_404_for_missing_file
|
|
89
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/width=100/assets/missing.jpg')
|
|
90
|
+
status, _, body = @app.call(env)
|
|
91
|
+
assert_equal 404, status
|
|
92
|
+
assert_equal ['file not exists on a server'], body
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# --- successful processing ---
|
|
96
|
+
|
|
97
|
+
def test_returns_200_for_valid_request
|
|
98
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/width=100/assets/photo.jpg')
|
|
99
|
+
status, headers, _ = @app.call(env)
|
|
100
|
+
assert_equal 200, status
|
|
101
|
+
assert_equal 'image/jpeg', headers['content-type']
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_valid_request_with_multiple_params
|
|
105
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/width=200,format=auto,quality=80/assets/photo.jpg')
|
|
106
|
+
status, = @app.call(env)
|
|
107
|
+
assert_equal 200, status
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def test_response_body_is_processed_content
|
|
111
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/width=100/assets/photo.jpg')
|
|
112
|
+
_, headers, body = @app.call(env)
|
|
113
|
+
assert_equal 'processed image data'.bytesize.to_s, headers['content-length']
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# --- fingerprinted filenames (Rails asset digest) ---
|
|
117
|
+
|
|
118
|
+
def test_strips_digest_fingerprint_from_filename
|
|
119
|
+
File.write(File.join(@tmpdir, 'photo.jpg'), 'fake jpeg content')
|
|
120
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/width=100/assets/photo-1a2b3c4d.jpg')
|
|
121
|
+
status, _, _ = @app.call(env)
|
|
122
|
+
assert_equal 200, status
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# --- custom cf_path_prefix ---
|
|
126
|
+
|
|
127
|
+
def test_custom_cf_path_prefix_does_not_intercept_default_prefix
|
|
128
|
+
app = RackResize::RackApp.new(
|
|
129
|
+
UPSTREAM,
|
|
130
|
+
assets_folder: @tmpdir,
|
|
131
|
+
processor: :sips,
|
|
132
|
+
save_resized: false,
|
|
133
|
+
cf_path_prefix: '/img'
|
|
134
|
+
)
|
|
135
|
+
env = Rack::MockRequest.env_for('/cdn-cgi/image/width=100/assets/photo.jpg')
|
|
136
|
+
_, _, body = app.call(env)
|
|
137
|
+
assert_equal ['upstream'], body
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# --- without upstream app ---
|
|
141
|
+
|
|
142
|
+
def test_initializes_without_upstream_app
|
|
143
|
+
app = RackResize::RackApp.new(assets_folder: @tmpdir, processor: :sips, save_resized: false)
|
|
144
|
+
assert_nil app.instance_variable_get(:@app)
|
|
145
|
+
end
|
|
146
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack_resize
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pavel Evstigneev
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-07-
|
|
10
|
+
date: 2026-07-16 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rack
|
|
@@ -35,9 +35,11 @@ executables: []
|
|
|
35
35
|
extensions: []
|
|
36
36
|
extra_rdoc_files: []
|
|
37
37
|
files:
|
|
38
|
+
- ".github/workflows/test.yml"
|
|
38
39
|
- ".gitignore"
|
|
39
40
|
- Gemfile
|
|
40
41
|
- README.md
|
|
42
|
+
- Rakefile
|
|
41
43
|
- config.ru
|
|
42
44
|
- lib/rack_resize.rb
|
|
43
45
|
- lib/rack_resize/configuration.rb
|
|
@@ -50,6 +52,13 @@ files:
|
|
|
50
52
|
- lib/rack_resize/rack_app.rb
|
|
51
53
|
- lib/rack_resize/rails_autoload.rb
|
|
52
54
|
- rack_resize.gemspec
|
|
55
|
+
- samples/image_1.jpeg
|
|
56
|
+
- samples/image_2.jpeg
|
|
57
|
+
- samples/image_3.jpeg
|
|
58
|
+
- samples/image_4.jpeg
|
|
59
|
+
- samples/index.html
|
|
60
|
+
- test/rack_app_test.rb
|
|
61
|
+
- test/test_helper.rb
|
|
53
62
|
homepage: https://github.com/paxa/rack_resize
|
|
54
63
|
licenses:
|
|
55
64
|
- MIT
|