image_size 3.0.1 → 3.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/check.yml +3 -9
- data/.github/workflows/rubocop.yml +16 -0
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +3 -3
- data/CHANGELOG.markdown +10 -0
- data/README.markdown +53 -3
- data/image_size.gemspec +3 -3
- data/lib/image_size/uri_reader.rb +82 -44
- data/lib/image_size.rb +1 -0
- data/spec/image_size/chunky_reader_spec.rb +5 -3
- data/spec/image_size_spec.rb +73 -22
- data/spec/images/empty +0 -0
- data/spec/test_server.rb +61 -0
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0873a78a9fb9f84f07d0389071379dda288330bd38ee7516b442ffde85a3af8
|
4
|
+
data.tar.gz: 0b9fffd2311efa1c24379686821289951a4cd2ec895c27325148a886a24ff57b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6dede99002af9b9fc32f9776e42019079abcd846370c06b2aeee812a73c9ec46dcb6c703d1ae454f807d532c1d6b740aabb999892a6ef610cd17311f6a9a7f0
|
7
|
+
data.tar.gz: 819d8a3b7797b1f12b59eb608ffdeda9338314a923ca54711143832685853ed36b9ae8d165fcfa242ce4e1d72aecd5a03bd11714aa7aee3b464722ea8bb4688f
|
data/.github/workflows/check.yml
CHANGED
@@ -19,8 +19,10 @@ jobs:
|
|
19
19
|
- '2.6'
|
20
20
|
- '2.7'
|
21
21
|
- '3.0'
|
22
|
+
- '3.1'
|
22
23
|
- jruby-9.1
|
23
24
|
- jruby-9.2
|
25
|
+
- jruby-9.3
|
24
26
|
fail-fast: false
|
25
27
|
steps:
|
26
28
|
- uses: actions/checkout@v2
|
@@ -50,6 +52,7 @@ jobs:
|
|
50
52
|
- '2.6'
|
51
53
|
- '2.7'
|
52
54
|
- '3.0'
|
55
|
+
- '3.1'
|
53
56
|
fail-fast: false
|
54
57
|
steps:
|
55
58
|
- uses: actions/checkout@v2
|
@@ -58,12 +61,3 @@ jobs:
|
|
58
61
|
ruby-version: "${{ matrix.ruby }}"
|
59
62
|
bundler-cache: true
|
60
63
|
- run: bundle exec rspec --format documentation
|
61
|
-
rubocop:
|
62
|
-
runs-on: ubuntu-latest
|
63
|
-
steps:
|
64
|
-
- uses: actions/checkout@v2
|
65
|
-
- uses: ruby/setup-ruby@v1
|
66
|
-
with:
|
67
|
-
ruby-version: '3.0'
|
68
|
-
bundler-cache: true
|
69
|
-
- run: bundle exec rubocop
|
@@ -0,0 +1,16 @@
|
|
1
|
+
name: rubocop
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
pull_request:
|
5
|
+
schedule:
|
6
|
+
- cron: 45 4 * * 3
|
7
|
+
jobs:
|
8
|
+
rubocop:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v2
|
12
|
+
- uses: ruby/setup-ruby@v1
|
13
|
+
with:
|
14
|
+
ruby-version: '3.1'
|
15
|
+
bundler-cache: true
|
16
|
+
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
@@ -53,6 +53,9 @@ Style/EmptyCaseCondition:
|
|
53
53
|
Style/Encoding:
|
54
54
|
Enabled: false
|
55
55
|
|
56
|
+
Style/FileRead:
|
57
|
+
Enabled: false
|
58
|
+
|
56
59
|
Style/HashEachMethods:
|
57
60
|
Enabled: true
|
58
61
|
|
@@ -77,6 +80,9 @@ Style/ParallelAssignment:
|
|
77
80
|
Style/SafeNavigation:
|
78
81
|
Enabled: false
|
79
82
|
|
83
|
+
Style/SlicingWithRange:
|
84
|
+
Enabled: false
|
85
|
+
|
80
86
|
Style/TrailingCommaInArrayLiteral:
|
81
87
|
EnforcedStyleForMultiline: comma
|
82
88
|
|
data/.rubocop_todo.yml
CHANGED
@@ -9,17 +9,17 @@
|
|
9
9
|
# Offense count: 8
|
10
10
|
# Configuration parameters: IgnoredMethods.
|
11
11
|
Metrics/AbcSize:
|
12
|
-
|
12
|
+
Enabled: false
|
13
13
|
|
14
14
|
# Offense count: 5
|
15
15
|
# Configuration parameters: IgnoredMethods.
|
16
16
|
Metrics/CyclomaticComplexity:
|
17
|
-
|
17
|
+
Enabled: false
|
18
18
|
|
19
19
|
# Offense count: 2
|
20
20
|
# Configuration parameters: IgnoredMethods.
|
21
21
|
Metrics/PerceivedComplexity:
|
22
|
-
|
22
|
+
Enabled: false
|
23
23
|
|
24
24
|
# Offense count: 8
|
25
25
|
# Cop supports --auto-correct.
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v3.1.0 (2022-09-17)
|
6
|
+
|
7
|
+
* Document experimental fetching from http server [#18](https://github.com/toy/image_size/issues/18) [@toy](https://github.com/toy)
|
8
|
+
* Improve experimental fetching of image meta from http server by reading only required amount of data when server does not support range header [@toy](https://github.com/toy)
|
9
|
+
|
10
|
+
## v3.0.2 (2022-05-19)
|
11
|
+
|
12
|
+
* Fix handling empty files [#20](https://github.com/toy/image_size/issues/20) [@toy](https://github.com/toy)
|
13
|
+
|
5
14
|
## v3.0.1 (2021-10-21)
|
6
15
|
|
7
16
|
* Fix reading file chunks starting after EOF and reading chunks non-consecutively [toy/image_optim_rails#12](https://github.com/toy/image_optim_rails/issues/12) [@toy](https://github.com/toy)
|
@@ -11,6 +20,7 @@
|
|
11
20
|
* Read only required chunks of data for files and seekable IOs [@toy](https://github.com/toy)
|
12
21
|
* Raise `FormatError` whenever reading data returns less data than expected [#12](https://github.com/toy/image_size/issues/12) [@toy](https://github.com/toy)
|
13
22
|
* Add `w`/`width` and `h`/`height` accessors to `Size` [@toy](https://github.com/toy)
|
23
|
+
* Experimental efficient fetching of image meta from http server supporting range [@toy](https://github.com/toy)
|
14
24
|
|
15
25
|
## v2.1.2 (2021-08-21)
|
16
26
|
|
data/README.markdown
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
[](https://rubygems.org/gems/image_size)
|
2
2
|
[](https://github.com/toy/image_size/actions/workflows/check.yml)
|
3
|
+
[](https://github.com/toy/image_size/actions/workflows/rubocop.yml)
|
3
4
|
|
4
5
|
# image_size
|
5
6
|
|
@@ -17,7 +18,7 @@ gem install image_size
|
|
17
18
|
Add to your `Gemfile`:
|
18
19
|
|
19
20
|
```ruby
|
20
|
-
gem 'image_size', '~>
|
21
|
+
gem 'image_size', '~> 3.0'
|
21
22
|
```
|
22
23
|
|
23
24
|
## Usage
|
@@ -53,7 +54,7 @@ require 'image_size'
|
|
53
54
|
image_size = ImageSize.new(ARGF)
|
54
55
|
```
|
55
56
|
|
56
|
-
Works with `open-uri
|
57
|
+
Works with `open-uri`, see [experimental HTTP server interface below](#experimental-fetch-image-meta-from-http-server):
|
57
58
|
|
58
59
|
```ruby
|
59
60
|
require 'image_size'
|
@@ -89,9 +90,58 @@ File.open('spec/images/jpeg/436x429.jpeg', 'rb') do |fh|
|
|
89
90
|
end
|
90
91
|
```
|
91
92
|
|
93
|
+
### Experimental: fetch image meta from HTTP server
|
94
|
+
|
95
|
+
If server recognises Range header, only needed chunks will be fetched even for TIFF images, otherwise required amount
|
96
|
+
of data will be fetched, in most cases first few kilobytes (TIFF images is an exception).
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
require 'image_size'
|
100
|
+
require 'image_size/uri_reader'
|
101
|
+
|
102
|
+
url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
|
103
|
+
p ImageSize.url(url).size
|
104
|
+
```
|
105
|
+
|
106
|
+
This interface is as fast as dedicated gem fastimage for images with meta information in the header:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
url = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/Mardin_1350660_1350692_33_images.jpg'
|
110
|
+
puts Benchmark.measure{ p FastImage.size(url) }
|
111
|
+
```
|
112
|
+
```
|
113
|
+
[9545, 6623]
|
114
|
+
0.004176 0.001974 0.006150 ( 0.282889)
|
115
|
+
```
|
116
|
+
```ruby
|
117
|
+
puts Benchmark.measure{ p ImageSize.url(url).size }
|
118
|
+
```
|
119
|
+
```
|
120
|
+
[9545, 6623]
|
121
|
+
0.005604 0.001406 0.007010 ( 0.238629)
|
122
|
+
```
|
123
|
+
|
124
|
+
And considerably faster for images with meta information at the end of file:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
url = "https://upload.wikimedia.org/wikipedia/commons/c/c7/Curiosity%27s_Vehicle_System_Test_Bed_%28VSTB%29_Rover_%28PIA15876%29.tif"
|
128
|
+
puts Benchmark.measure{ p FastImage.size(url) }
|
129
|
+
```
|
130
|
+
```
|
131
|
+
[7360, 4912]
|
132
|
+
0.331284 0.247295 0.578579 ( 6.027051)
|
133
|
+
```
|
134
|
+
```ruby
|
135
|
+
puts Benchmark.measure{ p ImageSize.url(url).size }
|
136
|
+
```
|
137
|
+
```
|
138
|
+
[7360, 4912]
|
139
|
+
0.006247 0.001045 0.007292 ( 0.197631)
|
140
|
+
```
|
141
|
+
|
92
142
|
## Licence
|
93
143
|
|
94
144
|
This code is free to use under the terms of the [Ruby's licence](LICENSE.txt).
|
95
145
|
|
96
146
|
Original author: Keisuke Minami <keisuke@rccn.com>.\
|
97
|
-
Further development 2010-
|
147
|
+
Further development 2010-2022 Ivan Kuchin https://github.com/toy/image_size
|
data/image_size.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_size'
|
5
|
-
s.version = '3.0
|
5
|
+
s.version = '3.1.0'
|
6
6
|
s.summary = %q{Measure image size using pure Ruby}
|
7
7
|
s.description = %q{Measure following file dimensions: apng, bmp, cur, gif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm}
|
8
8
|
s.homepage = "https://github.com/toy/#{s.name}"
|
@@ -22,8 +22,8 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.require_paths = %w[lib]
|
23
23
|
|
24
24
|
s.add_development_dependency 'rspec', '~> 3.0'
|
25
|
-
if RUBY_VERSION >= '2.
|
26
|
-
s.add_development_dependency 'rubocop', '~> 1.
|
25
|
+
if RUBY_VERSION >= '2.5'
|
26
|
+
s.add_development_dependency 'rubocop', '~> 1.22'
|
27
27
|
s.add_development_dependency 'rubocop-rspec', '~> 2.0'
|
28
28
|
end
|
29
29
|
end
|
@@ -6,65 +6,103 @@ require 'image_size/chunky_reader'
|
|
6
6
|
require 'net/https'
|
7
7
|
require 'uri'
|
8
8
|
|
9
|
-
#
|
9
|
+
# Experimental, not yet part of stable API
|
10
10
|
#
|
11
|
-
# It adds ability to fetch
|
12
|
-
# needed chunks if the server recognises Range header
|
11
|
+
# It adds ability to fetch image meta from HTTP server while downloading only
|
12
|
+
# needed chunks if the server recognises Range header, otherwise fetches only
|
13
|
+
# required amount of data
|
13
14
|
class ImageSize
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def initialize(uri, redirects = 5)
|
18
|
-
if !@http || @http.address != uri.host || @http.port != uri.port
|
19
|
-
@http.finish if @http
|
20
|
-
@http = Net::HTTP.new(uri.host, uri.port)
|
21
|
-
@http.use_ssl = true if uri.scheme == 'https'
|
22
|
-
@http.start
|
23
|
-
end
|
15
|
+
module URIReader # :nodoc:
|
16
|
+
module HTTPChunkyReader # :nodoc:
|
17
|
+
include ChunkyReader
|
24
18
|
|
25
|
-
|
26
|
-
|
19
|
+
def chunk_range_header(i)
|
20
|
+
{ 'Range' => "bytes=#{chunk_size * i}-#{(chunk_size * (i + 1)) - 1}" }
|
21
|
+
end
|
22
|
+
end
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
raise "Too many redirects: #{response['location']}" unless redirects > 0
|
24
|
+
class BodyReader # :nodoc:
|
25
|
+
include ChunkyReader
|
31
26
|
|
32
|
-
|
33
|
-
|
34
|
-
@
|
35
|
-
when Net::HTTPPartialContent
|
36
|
-
@chunks = { 0 => response.body }
|
37
|
-
else
|
38
|
-
raise "Unexpected response: #{response}"
|
27
|
+
def initialize(response)
|
28
|
+
@body = String.new
|
29
|
+
@body_reader = response.to_enum(:read_body)
|
39
30
|
end
|
40
|
-
end
|
41
31
|
|
42
|
-
|
43
|
-
|
32
|
+
def [](offset, length)
|
33
|
+
if @body_reader
|
34
|
+
begin
|
35
|
+
@body << @body_reader.next while @body.length < offset + length
|
36
|
+
rescue StopIteration, IOError
|
37
|
+
@body_reader = nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
44
41
|
@body[offset, length]
|
45
|
-
else
|
46
|
-
super
|
47
42
|
end
|
48
43
|
end
|
49
44
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
raise "Unexpected response: #{response}"
|
58
|
-
end
|
45
|
+
class RangeReader # :nodoc:
|
46
|
+
include HTTPChunkyReader
|
47
|
+
|
48
|
+
def initialize(http, request_uri, chunk0)
|
49
|
+
@http = http
|
50
|
+
@request_uri = request_uri
|
51
|
+
@chunks = { 0 => chunk0 }
|
59
52
|
end
|
60
53
|
|
61
|
-
|
54
|
+
def chunk(i)
|
55
|
+
unless @chunks.key?(i)
|
56
|
+
response = @http.get(@request_uri, chunk_range_header(i))
|
57
|
+
case response
|
58
|
+
when Net::HTTPPartialContent
|
59
|
+
@chunks[i] = response.body
|
60
|
+
else
|
61
|
+
raise "Unexpected response: #{response}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
@chunks[i]
|
66
|
+
end
|
62
67
|
end
|
63
68
|
|
64
|
-
|
69
|
+
class << self
|
70
|
+
include HTTPChunkyReader
|
71
|
+
|
72
|
+
def open(uri, max_redirects = 5)
|
73
|
+
http = nil
|
74
|
+
(max_redirects + 1).times do
|
75
|
+
unless http && http.address == uri.host && http.port == uri.port
|
76
|
+
http.finish if http
|
77
|
+
|
78
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
79
|
+
http.use_ssl = true if uri.scheme == 'https'
|
80
|
+
http.start
|
81
|
+
end
|
65
82
|
|
66
|
-
|
67
|
-
|
83
|
+
response = http.request_get(uri.request_uri, chunk_range_header(0)) do |response_with_unread_body|
|
84
|
+
case response_with_unread_body
|
85
|
+
when Net::HTTPOK
|
86
|
+
return yield BodyReader.new(response_with_unread_body)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
case response
|
91
|
+
when Net::HTTPRedirection
|
92
|
+
uri += response['location']
|
93
|
+
when Net::HTTPPartialContent
|
94
|
+
return yield RangeReader.new(http, uri.request_uri, response.body)
|
95
|
+
when Net::HTTPRequestedRangeNotSatisfiable
|
96
|
+
return yield StringReader.new('')
|
97
|
+
else
|
98
|
+
raise "Unexpected response: #{response}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
raise "Too many redirects: #{uri}"
|
103
|
+
ensure
|
104
|
+
http.finish if http.started?
|
105
|
+
end
|
68
106
|
end
|
69
107
|
end
|
70
108
|
|
@@ -72,7 +110,7 @@ class ImageSize
|
|
72
110
|
class << self
|
73
111
|
def open_with_uri(input, &block)
|
74
112
|
if input.is_a?(URI)
|
75
|
-
|
113
|
+
URIReader.open(input, &block)
|
76
114
|
else
|
77
115
|
open_without_uri(input, &block)
|
78
116
|
end
|
data/lib/image_size.rb
CHANGED
@@ -76,6 +76,7 @@ private
|
|
76
76
|
def detect_format(ir)
|
77
77
|
head = ir[0, 1024]
|
78
78
|
case
|
79
|
+
when head.nil? || head.empty? then nil
|
79
80
|
when head[0, 6] =~ /GIF8[79]a/ then :gif
|
80
81
|
when head[0, 8] == "\211PNG\r\n\032\n" then detect_png_type(ir)
|
81
82
|
when head[0, 8] == "\212MNG\r\n\032\n" then :mng
|
@@ -56,9 +56,11 @@ describe ImageSize::ChunkyReader do
|
|
56
56
|
offsets.each do |offset_b|
|
57
57
|
length = offset_b - offset
|
58
58
|
expect(reader[offset, length]).to eq(data[offset, length]),
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
[
|
60
|
+
"for offset #{offset} and length #{length}",
|
61
|
+
"expected: #{data[offset, length].inspect}",
|
62
|
+
" got: #{reader[offset, length].inspect}",
|
63
|
+
].join("\n")
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
data/spec/image_size_spec.rb
CHANGED
@@ -7,31 +7,20 @@ require 'image_size/uri_reader'
|
|
7
7
|
|
8
8
|
require 'tempfile'
|
9
9
|
require 'shellwords'
|
10
|
-
|
10
|
+
|
11
|
+
require 'test_server'
|
11
12
|
|
12
13
|
describe ImageSize do
|
13
14
|
before :all do
|
14
|
-
@server =
|
15
|
-
:Logger => WEBrick::Log.new(StringIO.new),
|
16
|
-
:AccessLog => [],
|
17
|
-
:BindAddress => '127.0.0.1',
|
18
|
-
:Port => 0, # get the next available port
|
19
|
-
:DocumentRoot => '.',
|
20
|
-
})
|
21
|
-
@server_thread = Thread.new{ @server.start }
|
22
|
-
@server_base_url = URI("http://127.0.0.1:#{@server.config[:Port]}/")
|
15
|
+
@server = TestServer.new
|
23
16
|
end
|
24
17
|
|
25
18
|
after :all do
|
26
|
-
@server.
|
27
|
-
@server_thread.join
|
19
|
+
@server.finish
|
28
20
|
end
|
29
21
|
|
30
|
-
|
31
|
-
|
32
|
-
(Dir['spec/images/*/*.*'] + [__FILE__[%r{spec/.+?\z}]]).each do |path|
|
33
|
-
filesize = File.size(path)
|
34
|
-
warn "#{path} is too big #{filesize} (max #{max_filesize})" if filesize > max_filesize
|
22
|
+
Dir['spec/**/*'].each do |path|
|
23
|
+
next unless File.file?(path)
|
35
24
|
|
36
25
|
describe "for #{path}" do
|
37
26
|
let(:name){ File.basename(path) }
|
@@ -49,6 +38,15 @@ describe ImageSize do
|
|
49
38
|
}
|
50
39
|
end
|
51
40
|
let(:file_data){ File.open(path, 'rb', &:read) }
|
41
|
+
let(:file_size){ file_data.length }
|
42
|
+
|
43
|
+
before do
|
44
|
+
max_file_size = 16_384
|
45
|
+
|
46
|
+
if file_size > max_file_size
|
47
|
+
raise "reduce resulting gem size, #{path} is too big (#{file_size} > #{max_file_size})"
|
48
|
+
end
|
49
|
+
end
|
52
50
|
|
53
51
|
context 'given as data' do
|
54
52
|
it 'gets format and dimensions' do
|
@@ -65,7 +63,11 @@ describe ImageSize do
|
|
65
63
|
image_size = ImageSize.new(io)
|
66
64
|
expect(image_size).to have_attributes(attributes)
|
67
65
|
expect(io).not_to be_closed
|
68
|
-
|
66
|
+
if file_size.zero?
|
67
|
+
expect(io.pos).to be_zero
|
68
|
+
else
|
69
|
+
expect(io.pos).to_not be_zero
|
70
|
+
end
|
69
71
|
io.rewind
|
70
72
|
expect(io.read).to eq(file_data)
|
71
73
|
end
|
@@ -102,7 +104,11 @@ describe ImageSize do
|
|
102
104
|
image_size = ImageSize.new(io)
|
103
105
|
expect(image_size).to have_attributes(attributes)
|
104
106
|
expect(io).not_to be_closed
|
105
|
-
|
107
|
+
if file_size.zero?
|
108
|
+
expect(io.pos).to be_zero
|
109
|
+
else
|
110
|
+
expect(io.pos).to_not be_zero
|
111
|
+
end
|
106
112
|
io.rewind
|
107
113
|
expect(io.read).to eq(file_data)
|
108
114
|
end
|
@@ -117,9 +123,54 @@ describe ImageSize do
|
|
117
123
|
end
|
118
124
|
|
119
125
|
context 'fetching from webserver' do
|
120
|
-
|
121
|
-
|
122
|
-
|
126
|
+
let(:file_url){ @server.base_url + path }
|
127
|
+
|
128
|
+
context 'supporting range' do
|
129
|
+
context 'without redirects' do
|
130
|
+
it 'gets format and dimensions' do
|
131
|
+
image_size = ImageSize.url(file_url)
|
132
|
+
expect(image_size).to have_attributes(attributes)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with redirects' do
|
137
|
+
it 'gets format and dimensions' do
|
138
|
+
image_size = ImageSize.url("#{file_url}?redirect=5")
|
139
|
+
expect(image_size).to have_attributes(attributes)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'with too many redirects' do
|
144
|
+
it 'gets format and dimensions' do
|
145
|
+
expect do
|
146
|
+
ImageSize.url("#{file_url}?redirect=6")
|
147
|
+
end.to raise_error(/Too many redirects/)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'not supporting range' do
|
153
|
+
context 'without redirects' do
|
154
|
+
it 'gets format and dimensions' do
|
155
|
+
image_size = ImageSize.url("#{file_url}?ignore_range")
|
156
|
+
expect(image_size).to have_attributes(attributes)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'with redirects' do
|
161
|
+
it 'gets format and dimensions' do
|
162
|
+
image_size = ImageSize.url("#{file_url}?ignore_range&redirect=5")
|
163
|
+
expect(image_size).to have_attributes(attributes)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'with too many redirects' do
|
168
|
+
it 'gets format and dimensions' do
|
169
|
+
expect do
|
170
|
+
ImageSize.url("#{file_url}?ignore_range&redirect=6")
|
171
|
+
end.to raise_error(/Too many redirects/)
|
172
|
+
end
|
173
|
+
end
|
123
174
|
end
|
124
175
|
end
|
125
176
|
end
|
data/spec/images/empty
ADDED
File without changes
|
data/spec/test_server.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'webrick'
|
4
|
+
|
5
|
+
class TestServer
|
6
|
+
attr_reader :base_url
|
7
|
+
|
8
|
+
def initialize(host = '127.0.0.1')
|
9
|
+
server_options = {
|
10
|
+
:Logger => WEBrick::Log.new(StringIO.new),
|
11
|
+
:AccessLog => [],
|
12
|
+
:BindAddress => host,
|
13
|
+
:Port => 0, # get the next available port
|
14
|
+
:DocumentRoot => '.',
|
15
|
+
:RequestCallback => proc do |req, res|
|
16
|
+
redirect = req.query['redirect'].to_i
|
17
|
+
if redirect > 0
|
18
|
+
res.set_redirect(
|
19
|
+
WEBrick::HTTPStatus::TemporaryRedirect,
|
20
|
+
[
|
21
|
+
req.request_uri.port == @base_url.port ? @second_url : @base_url,
|
22
|
+
req.request_uri.request_uri,
|
23
|
+
"?#{encode_www_form(req.query.merge('redirect' => redirect - 1))}",
|
24
|
+
].inject(:+)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
req.header.delete('range') if req.query['ignore_range']
|
29
|
+
end,
|
30
|
+
}
|
31
|
+
|
32
|
+
@server = WEBrick::HTTPServer.new(server_options)
|
33
|
+
@server.listen(host, 0) # listen on second port
|
34
|
+
|
35
|
+
@base_url = URI("http://#{host}:#{@server.listeners[0].addr[1]}/")
|
36
|
+
@second_url = URI("http://#{host}:#{@server.listeners[1].addr[1]}/")
|
37
|
+
|
38
|
+
@thread = Thread.new{ @server.start }
|
39
|
+
end
|
40
|
+
|
41
|
+
def finish
|
42
|
+
@server.shutdown
|
43
|
+
@thread.join
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
if URI.respond_to?(:encode_www_form)
|
49
|
+
def encode_www_form(h)
|
50
|
+
URI.encode_www_form(h)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
require 'cgi'
|
54
|
+
|
55
|
+
def encode_www_form(h)
|
56
|
+
h.map do |k, v|
|
57
|
+
"#{CGI.escape(k)}=#{CGI.escape(v.to_s)}"
|
58
|
+
end.join('&')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_size
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keisuke Minami
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-09-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '1.
|
34
|
+
version: '1.22'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '1.
|
41
|
+
version: '1.22'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rubocop-rspec
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,6 +61,7 @@ extensions: []
|
|
61
61
|
extra_rdoc_files: []
|
62
62
|
files:
|
63
63
|
- ".github/workflows/check.yml"
|
64
|
+
- ".github/workflows/rubocop.yml"
|
64
65
|
- ".gitignore"
|
65
66
|
- ".rubocop.yml"
|
66
67
|
- ".rubocop_todo.yml"
|
@@ -85,6 +86,7 @@ files:
|
|
85
86
|
- spec/images/bmp/v3-bottom2top.42x50.bmp
|
86
87
|
- spec/images/bmp/v3-top2bottom.42x50.bmp
|
87
88
|
- spec/images/cur/32x256.cur
|
89
|
+
- spec/images/empty
|
88
90
|
- spec/images/gif/668x481.gif
|
89
91
|
- spec/images/ico/32x256.ico
|
90
92
|
- spec/images/jp2/163x402.jp2
|
@@ -118,13 +120,14 @@ files:
|
|
118
120
|
- spec/images/xbm/crlf.16x32.xbm
|
119
121
|
- spec/images/xpm/24x32.xpm
|
120
122
|
- spec/images/xpm/crlf.24x32.xpm
|
123
|
+
- spec/test_server.rb
|
121
124
|
homepage: https://github.com/toy/image_size
|
122
125
|
licenses:
|
123
126
|
- Ruby
|
124
127
|
metadata:
|
125
128
|
bug_tracker_uri: https://github.com/toy/image_size/issues
|
126
129
|
changelog_uri: https://github.com/toy/image_size/blob/master/CHANGELOG.markdown
|
127
|
-
documentation_uri: https://www.rubydoc.info/gems/image_size/3.0
|
130
|
+
documentation_uri: https://www.rubydoc.info/gems/image_size/3.1.0
|
128
131
|
source_code_uri: https://github.com/toy/image_size
|
129
132
|
post_install_message:
|
130
133
|
rdoc_options: []
|
@@ -141,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
144
|
- !ruby/object:Gem::Version
|
142
145
|
version: '0'
|
143
146
|
requirements: []
|
144
|
-
rubygems_version: 3.
|
147
|
+
rubygems_version: 3.3.11
|
145
148
|
signing_key:
|
146
149
|
specification_version: 4
|
147
150
|
summary: Measure image size using pure Ruby
|
@@ -154,6 +157,7 @@ test_files:
|
|
154
157
|
- spec/images/bmp/v3-bottom2top.42x50.bmp
|
155
158
|
- spec/images/bmp/v3-top2bottom.42x50.bmp
|
156
159
|
- spec/images/cur/32x256.cur
|
160
|
+
- spec/images/empty
|
157
161
|
- spec/images/gif/668x481.gif
|
158
162
|
- spec/images/ico/32x256.ico
|
159
163
|
- spec/images/jp2/163x402.jp2
|
@@ -187,3 +191,4 @@ test_files:
|
|
187
191
|
- spec/images/xbm/crlf.16x32.xbm
|
188
192
|
- spec/images/xpm/24x32.xpm
|
189
193
|
- spec/images/xpm/crlf.24x32.xpm
|
194
|
+
- spec/test_server.rb
|