image_size 3.4.0 → 3.6.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/dependabot.yml +8 -0
- data/.github/workflows/check.yml +13 -19
- data/.github/workflows/rubocop.yml +4 -2
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +0 -6
- data/CHANGELOG.markdown +16 -3
- data/README.markdown +50 -3
- data/image_size.gemspec +15 -6
- data/lib/image_size/chunky_reader.rb +2 -2
- data/lib/image_size/isobmff.rb +2 -2
- data/lib/image_size/media_types.rb +1 -0
- data/lib/image_size/reader.rb +4 -3
- data/lib/image_size/seekable_io_reader.rb +4 -0
- data/lib/image_size/stream_io_reader.rb +6 -0
- data/lib/image_size/string_reader.rb +4 -0
- data/lib/image_size/uri_reader.rb +61 -10
- data/lib/image_size.rb +118 -29
- data/spec/image_size/chunky_reader_spec.rb +1 -1
- data/spec/image_size/seekable_io_reader_spec.rb +19 -24
- data/spec/image_size_spec.rb +263 -43
- data/spec/images/icns/16x12.icns +0 -0
- data/spec/images/icns/afp_scanpix_leta_pilipey_kyiv.256x256@1x.icns +0 -0
- data/spec/images/icns/reuters_scanpix_leta_garanich_kyiv.256x256@2x.icns +0 -0
- data/spec/images/icns/toc.512x512@1x.icns +0 -0
- data/spec/images/icns/toc.512x512@2x.icns +0 -0
- data/spec/images/svg/768b.430x430.svg +11 -0
- data/spec/test_server.rb +29 -3
- metadata +19 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e7880ff3fdbcfdbbc6e3248c79ef59adea338f21c63c285323c5b01bdf699477
|
|
4
|
+
data.tar.gz: b8ce40e97bc91a2f7e91a9ce3f47d17f06aa38a6a28f7e534837c1f668cc51e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 027e0f32e86acf19b92cb00404dfb2b26f0989ed13d07247512ff024d058a245d62b3b252e2605ff1d79a41636cb87874f2f556f3e2cdcaf2727efe3fc91efe2
|
|
7
|
+
data.tar.gz: b8a5074adaa1d08d6b3b8d9d1a5da5c5239e1ea46b345fc13ffbf5ba75736d826beaeceb38b09aec7267f6c934856c1237c9c514ecad3fb6e9701b0846352f0d
|
data/.github/workflows/check.yml
CHANGED
|
@@ -4,12 +4,17 @@ on:
|
|
|
4
4
|
pull_request:
|
|
5
5
|
schedule:
|
|
6
6
|
- cron: 45 4 * * 3
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
7
9
|
jobs:
|
|
8
10
|
check:
|
|
9
|
-
runs-on: ubuntu-
|
|
11
|
+
runs-on: ubuntu-22.04
|
|
10
12
|
strategy:
|
|
11
13
|
matrix:
|
|
12
14
|
ruby:
|
|
15
|
+
- '1.9.3'
|
|
16
|
+
- '2.0'
|
|
17
|
+
- '2.1'
|
|
13
18
|
- '2.3'
|
|
14
19
|
- '2.4'
|
|
15
20
|
- '2.5'
|
|
@@ -19,31 +24,18 @@ jobs:
|
|
|
19
24
|
- '3.1'
|
|
20
25
|
- '3.2'
|
|
21
26
|
- '3.3'
|
|
22
|
-
-
|
|
27
|
+
- '3.4'
|
|
28
|
+
- '4.0'
|
|
23
29
|
- jruby-9.4
|
|
30
|
+
- jruby-10.1
|
|
24
31
|
fail-fast: false
|
|
25
32
|
steps:
|
|
26
|
-
- uses: actions/checkout@
|
|
33
|
+
- uses: actions/checkout@v6
|
|
27
34
|
- uses: ruby/setup-ruby@v1
|
|
28
35
|
with:
|
|
29
36
|
ruby-version: "${{ matrix.ruby }}"
|
|
30
37
|
bundler-cache: true
|
|
31
38
|
- run: bundle exec rspec --format documentation
|
|
32
|
-
legacy:
|
|
33
|
-
runs-on: ubuntu-latest
|
|
34
|
-
container: ${{ matrix.container }}
|
|
35
|
-
strategy:
|
|
36
|
-
matrix:
|
|
37
|
-
container:
|
|
38
|
-
- rspec/ci:1.9.3
|
|
39
|
-
- ruby:2.0
|
|
40
|
-
- ruby:2.1
|
|
41
|
-
- ruby:2.2
|
|
42
|
-
fail-fast: false
|
|
43
|
-
steps:
|
|
44
|
-
- uses: actions/checkout@v3
|
|
45
|
-
- run: bundle install
|
|
46
|
-
- run: bundle exec rspec --format documentation
|
|
47
39
|
windows:
|
|
48
40
|
runs-on: windows-latest
|
|
49
41
|
strategy:
|
|
@@ -55,9 +47,11 @@ jobs:
|
|
|
55
47
|
- '3.1'
|
|
56
48
|
- '3.2'
|
|
57
49
|
- '3.3'
|
|
50
|
+
- '3.4'
|
|
51
|
+
- '4.0'
|
|
58
52
|
fail-fast: false
|
|
59
53
|
steps:
|
|
60
|
-
- uses: actions/checkout@
|
|
54
|
+
- uses: actions/checkout@v6
|
|
61
55
|
- uses: ruby/setup-ruby@v1
|
|
62
56
|
with:
|
|
63
57
|
ruby-version: "${{ matrix.ruby }}"
|
|
@@ -4,13 +4,15 @@ on:
|
|
|
4
4
|
pull_request:
|
|
5
5
|
schedule:
|
|
6
6
|
- cron: 45 4 * * 3
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
7
9
|
jobs:
|
|
8
10
|
rubocop:
|
|
9
11
|
runs-on: ubuntu-latest
|
|
10
12
|
steps:
|
|
11
|
-
- uses: actions/checkout@
|
|
13
|
+
- uses: actions/checkout@v6
|
|
12
14
|
- uses: ruby/setup-ruby@v1
|
|
13
15
|
with:
|
|
14
|
-
ruby-version: '
|
|
16
|
+
ruby-version: '4'
|
|
15
17
|
bundler-cache: true
|
|
16
18
|
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.markdown
CHANGED
|
@@ -2,11 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## unreleased
|
|
4
4
|
|
|
5
|
+
## v3.6.0 (2026-05-26)
|
|
6
|
+
|
|
7
|
+
* Support `.icns` Apple Icon Image format [@toy](https://github.com/toy)
|
|
8
|
+
|
|
9
|
+
## v3.5.0 (2026-05-03)
|
|
10
|
+
|
|
11
|
+
* Add `byte_size` method to expose the size of the image data in bytes [#27](https://github.com/toy/image_size/pull/27) [@dgodd](https://github.com/dgodd)
|
|
12
|
+
* Add minimal validation of `dpi` global configuration [@toy](https://github.com/toy)
|
|
13
|
+
* Make `chunk_size` globally configurable [@toy](https://github.com/toy)
|
|
14
|
+
* Make `max_redirects` globally configurable [@toy](https://github.com/toy)
|
|
15
|
+
* Prevent requesting chunks over http after end of file [#29](https://github.com/toy/image_size/issues/29) [@toy](https://github.com/toy)
|
|
16
|
+
* Add ability to restrict fetched URIs by setting `uri_checker` proc [@toy](https://github.com/toy)
|
|
17
|
+
|
|
5
18
|
## v3.4.0 (2024-01-16)
|
|
6
19
|
|
|
7
|
-
* Provide access to media types using media_type and media_types methods [#22](https://github.com/toy/image_size/issues/22) [@toy](https://github.com/toy)
|
|
8
|
-
* Allow fetching from HTTP server by requiring image_size/uri [@toy](https://github.com/toy)
|
|
9
|
-
* Fix for ArgumentError when requiring only image_size/uri_reader (without image_size) [@toy](https://github.com/toy)
|
|
20
|
+
* Provide access to media types using `media_type` and `media_types` methods [#22](https://github.com/toy/image_size/issues/22) [@toy](https://github.com/toy)
|
|
21
|
+
* Allow fetching from HTTP server by requiring `image_size/uri` [@toy](https://github.com/toy)
|
|
22
|
+
* Fix for `ArgumentError` when requiring only `image_size/uri_reader` (without image_size) [@toy](https://github.com/toy)
|
|
10
23
|
* Require ruby 1.9.3 [@toy](https://github.com/toy)
|
|
11
24
|
|
|
12
25
|
## v3.3.0 (2023-05-30)
|
data/README.markdown
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[](https://rubygems.org/gems/image_size)
|
|
2
|
-
[](https://github.com/toy/image_size/actions/workflows/check.yml)
|
|
3
3
|
[](https://github.com/toy/image_size/actions/workflows/rubocop.yml)
|
|
4
4
|
|
|
5
5
|
# image_size
|
|
6
6
|
|
|
7
7
|
Measure image size/dimensions using pure Ruby.
|
|
8
|
-
Formats: `apng`, `avif`, `bmp`, `cur`, `emf`, `gif`, `heic`, `heif`, `ico`, `j2c`, `jp2`, `jpeg`, `jpx`, `mng`, `pam`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `svg`, `swf`, `tiff`, `webp`, `xbm`, `xpm`.
|
|
8
|
+
Formats: `apng`, `avif`, `bmp`, `cur`, `emf`, `gif`, `heic`, `heif`, `icns`, `ico`, `j2c`, `jp2`, `jpeg`, `jpx`, `mng`, `pam`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `svg`, `swf`, `tiff`, `webp`, `xbm`, `xpm`.
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
@@ -40,6 +40,7 @@ image_size.size.w #=> 436
|
|
|
40
40
|
image_size.size.h #=> 429
|
|
41
41
|
image_size.media_type #=> "image/jpeg"
|
|
42
42
|
image_size.media_types #=> ["image/jpeg"]
|
|
43
|
+
image_size.byte_size #=> 10938
|
|
43
44
|
```
|
|
44
45
|
|
|
45
46
|
Or using `IO` object:
|
|
@@ -92,6 +93,20 @@ File.open('spec/images/jpeg/436x429.jpeg', 'rb') do |fh|
|
|
|
92
93
|
end
|
|
93
94
|
```
|
|
94
95
|
|
|
96
|
+
### Configuration
|
|
97
|
+
|
|
98
|
+
DPI used for converting `svg` and `emf` dimensions can be configured from default 72:
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
ImageSize.dpi = 150
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Chunk size used for reading files, IO and from remote can be configured from default 4096:
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
ImageSize.chunk_size = 256
|
|
108
|
+
```
|
|
109
|
+
|
|
95
110
|
### Experimental: fetch image meta from HTTP server
|
|
96
111
|
|
|
97
112
|
If server recognises Range header, only needed chunks will be fetched even for TIFF images, otherwise required amount
|
|
@@ -140,9 +155,41 @@ puts Benchmark.measure{ p ImageSize.url(url).size }
|
|
|
140
155
|
0.006247 0.001045 0.007292 ( 0.197631)
|
|
141
156
|
```
|
|
142
157
|
|
|
158
|
+
#### Configuration
|
|
159
|
+
|
|
160
|
+
Maximum number of redirects can be configured from default 5:
|
|
161
|
+
|
|
162
|
+
```ruby
|
|
163
|
+
ImageSize.max_redirects = 10
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Or redirects can be disabled:
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
ImageSize.max_redirects = 0
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
A url checker can be added to reduce SSRF risk:
|
|
173
|
+
|
|
174
|
+
```ruby
|
|
175
|
+
ImageSize.uri_checker = lambda do |uri|
|
|
176
|
+
raise 'host is not allowed' unless uri.host == 'upload.wikipedia.org'
|
|
177
|
+
end
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Alternatively `private_address_check` gem can be of help:
|
|
181
|
+
|
|
182
|
+
```ruby
|
|
183
|
+
require "private_address_check/tcpsocket_ext"
|
|
184
|
+
|
|
185
|
+
PrivateAddressCheck.only_public_connections do
|
|
186
|
+
ImageSize.url(url).size
|
|
187
|
+
end
|
|
188
|
+
```
|
|
189
|
+
|
|
143
190
|
## Licence
|
|
144
191
|
|
|
145
192
|
This code is free to use under the terms of the [Ruby's licence](LICENSE.txt).
|
|
146
193
|
|
|
147
194
|
Original author: Keisuke Minami <keisuke@rccn.com>.\
|
|
148
|
-
Further development 2010-
|
|
195
|
+
Further development 2010-2026 Ivan Kuchin https://github.com/toy/image_size
|
data/image_size.gemspec
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = 'image_size'
|
|
5
|
-
s.version = '3.
|
|
5
|
+
s.version = '3.6.0'
|
|
6
6
|
s.summary = %q{Measure image size/dimensions using pure Ruby}
|
|
7
|
-
s.description = %q{Measure following file dimensions: apng, avif, bmp, cur, emf, gif, heic, heif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm}
|
|
7
|
+
s.description = %q{Measure following file dimensions: apng, avif, bmp, cur, emf, gif, heic, heif, icns, 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}"
|
|
9
9
|
s.authors = ['Keisuke Minami', 'Ivan Kuchin']
|
|
10
10
|
s.license = 'Ruby'
|
|
@@ -16,11 +16,20 @@ Gem::Specification.new do |s|
|
|
|
16
16
|
'changelog_uri' => "https://github.com/toy/#{s.name}/blob/master/CHANGELOG.markdown",
|
|
17
17
|
'documentation_uri' => "https://www.rubydoc.info/gems/#{s.name}/#{s.version}",
|
|
18
18
|
'source_code_uri' => "https://github.com/toy/#{s.name}",
|
|
19
|
-
}
|
|
19
|
+
} if s.respond_to?(:metadata=)
|
|
20
20
|
|
|
21
|
-
s.files
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
s.files = Dir[*%w[
|
|
22
|
+
.gitignore
|
|
23
|
+
.rubocop*.yml
|
|
24
|
+
Gemfile
|
|
25
|
+
LICENSE.txt
|
|
26
|
+
GPL
|
|
27
|
+
*.markdown
|
|
28
|
+
*.gemspec
|
|
29
|
+
{.github,lib,spec}/**/{*,.gitattributes}
|
|
30
|
+
]].reject(&File.method(:directory?))
|
|
31
|
+
|
|
32
|
+
s.test_files = Dir['spec/**/{*,.gitattributes}'].reject(&File.method(:directory?))
|
|
24
33
|
s.require_paths = %w[lib]
|
|
25
34
|
|
|
26
35
|
s.add_development_dependency 'rspec', '~> 3.0'
|
|
@@ -8,7 +8,7 @@ class ImageSize
|
|
|
8
8
|
|
|
9
9
|
# Size of a chunk in which to read
|
|
10
10
|
def chunk_size
|
|
11
|
-
|
|
11
|
+
@chunk_size ||= ImageSize.chunk_size
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Including class should define method chunk that accepts the chunk number
|
|
@@ -18,7 +18,7 @@ class ImageSize
|
|
|
18
18
|
# substring, behaves same as str[start, length] except start can't be
|
|
19
19
|
# negative.
|
|
20
20
|
def [](offset, length)
|
|
21
|
-
|
|
21
|
+
fail ArgumentError, "expected offset not to be negative, got #{offset}" if offset < 0
|
|
22
22
|
return if length < 0
|
|
23
23
|
|
|
24
24
|
first = offset / chunk_size
|
data/lib/image_size/isobmff.rb
CHANGED
|
@@ -56,9 +56,9 @@ class ImageSize
|
|
|
56
56
|
when 1
|
|
57
57
|
size = reader.unpack1(offset + 8, 8, 'Q>')
|
|
58
58
|
relative_data_offset += 8
|
|
59
|
-
|
|
59
|
+
fail FormatError, "Unexpected ISOBMFF xl-box size #{size}" if size < 16
|
|
60
60
|
when 2..7
|
|
61
|
-
|
|
61
|
+
fail FormatError, "Reserved ISOBMFF box size #{size}"
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
attributes = {
|
data/lib/image_size/reader.rb
CHANGED
|
@@ -30,14 +30,15 @@ class ImageSize
|
|
|
30
30
|
when input.is_a?(Pathname)
|
|
31
31
|
input.open('rb'){ |f| yield for_io(f) }
|
|
32
32
|
else
|
|
33
|
-
|
|
33
|
+
fail ArgumentError, 'expected a String, a Pathname, a StringIO or an object responding to read and eof? ' \
|
|
34
|
+
"(IO), got #{input.class}"
|
|
34
35
|
end
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
private
|
|
38
39
|
|
|
39
40
|
def for_io(io)
|
|
40
|
-
if io.respond_to?(:stat) && !io.stat.file?
|
|
41
|
+
if (io.respond_to?(:stat) && !io.stat.file?) || !io.respond_to?(:seek)
|
|
41
42
|
StreamIOReader.new(io)
|
|
42
43
|
else
|
|
43
44
|
begin
|
|
@@ -54,7 +55,7 @@ class ImageSize
|
|
|
54
55
|
chunk = self[offset, length]
|
|
55
56
|
|
|
56
57
|
unless chunk && chunk.length == length
|
|
57
|
-
|
|
58
|
+
fail FormatError, "Expected #{length} bytes at offset #{offset}, got #{chunk.inspect}"
|
|
58
59
|
end
|
|
59
60
|
|
|
60
61
|
chunk
|
|
@@ -17,17 +17,24 @@ class ImageSize
|
|
|
17
17
|
module HTTPChunkyReader # :nodoc:
|
|
18
18
|
include ChunkyReader
|
|
19
19
|
|
|
20
|
+
def chunk_start(i)
|
|
21
|
+
chunk_size * i
|
|
22
|
+
end
|
|
23
|
+
|
|
20
24
|
def chunk_range_header(i)
|
|
21
|
-
{ 'Range' => "bytes=#{
|
|
25
|
+
{ 'Range' => "bytes=#{chunk_start(i)}-#{chunk_start(i + 1) - 1}" }
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
class BodyReader # :nodoc:
|
|
26
30
|
include ChunkyReader
|
|
27
31
|
|
|
32
|
+
attr_reader :byte_size
|
|
33
|
+
|
|
28
34
|
def initialize(response)
|
|
29
35
|
@body = String.new
|
|
30
36
|
@body_reader = response.to_enum(:read_body)
|
|
37
|
+
@byte_size = response.content_length
|
|
31
38
|
end
|
|
32
39
|
|
|
33
40
|
def [](offset, length)
|
|
@@ -46,20 +53,32 @@ class ImageSize
|
|
|
46
53
|
class RangeReader # :nodoc:
|
|
47
54
|
include HTTPChunkyReader
|
|
48
55
|
|
|
49
|
-
|
|
56
|
+
attr_reader :byte_size
|
|
57
|
+
|
|
58
|
+
def initialize(http, request_uri, chunk0, byte_size)
|
|
50
59
|
@http = http
|
|
51
60
|
@request_uri = request_uri
|
|
52
61
|
@chunks = { 0 => chunk0 }
|
|
62
|
+
@byte_size = byte_size
|
|
63
|
+
@last_chunk = nil
|
|
53
64
|
end
|
|
54
65
|
|
|
55
66
|
def chunk(i)
|
|
67
|
+
return if @byte_size && chunk_start(i) >= @byte_size
|
|
68
|
+
return if @last_chunk && i > @last_chunk
|
|
69
|
+
|
|
56
70
|
unless @chunks.key?(i)
|
|
57
71
|
response = @http.get(@request_uri, chunk_range_header(i))
|
|
58
72
|
case response
|
|
59
73
|
when Net::HTTPPartialContent
|
|
60
|
-
|
|
74
|
+
body = response.body
|
|
75
|
+
@chunks[i] = body
|
|
76
|
+
@last_chunk = i if body.length < chunk_size
|
|
77
|
+
when Net::HTTPRequestedRangeNotSatisfiable
|
|
78
|
+
@chunks[i] = nil
|
|
79
|
+
@last_chunk = i if !@last_chunk || @last_chunk > i
|
|
61
80
|
else
|
|
62
|
-
|
|
81
|
+
fail "Unexpected response: #{response}"
|
|
63
82
|
end
|
|
64
83
|
end
|
|
65
84
|
|
|
@@ -70,9 +89,11 @@ class ImageSize
|
|
|
70
89
|
class << self
|
|
71
90
|
include HTTPChunkyReader
|
|
72
91
|
|
|
73
|
-
def open(uri
|
|
92
|
+
def open(uri)
|
|
74
93
|
http = nil
|
|
75
|
-
(max_redirects + 1).times do
|
|
94
|
+
(ImageSize.max_redirects + 1).times do
|
|
95
|
+
ImageSize.uri_checker.call(uri)
|
|
96
|
+
|
|
76
97
|
unless http && http.address == uri.host && http.port == uri.port
|
|
77
98
|
http.finish if http
|
|
78
99
|
|
|
@@ -92,17 +113,19 @@ class ImageSize
|
|
|
92
113
|
when Net::HTTPRedirection
|
|
93
114
|
uri += response['location']
|
|
94
115
|
when Net::HTTPPartialContent
|
|
95
|
-
|
|
116
|
+
m = response['content-range'].match(%r{\bbytes\s+\d+-\d+/(\d+)}i) if response['content-range']
|
|
117
|
+
byte_size = m[1].to_i if m
|
|
118
|
+
return yield RangeReader.new(http, uri.request_uri, response.body, byte_size)
|
|
96
119
|
when Net::HTTPRequestedRangeNotSatisfiable
|
|
97
120
|
return yield StringReader.new('')
|
|
98
121
|
else
|
|
99
|
-
|
|
122
|
+
fail "Unexpected response: #{response}"
|
|
100
123
|
end
|
|
101
124
|
end
|
|
102
125
|
|
|
103
|
-
|
|
126
|
+
fail "Too many redirects: #{uri}"
|
|
104
127
|
ensure
|
|
105
|
-
http.finish if http.started?
|
|
128
|
+
http.finish if http && http.started?
|
|
106
129
|
end
|
|
107
130
|
end
|
|
108
131
|
end
|
|
@@ -124,4 +147,32 @@ class ImageSize
|
|
|
124
147
|
def self.url(url)
|
|
125
148
|
new(url.is_a?(URI) ? url : URI(url))
|
|
126
149
|
end
|
|
150
|
+
|
|
151
|
+
# Maximum number of redirects
|
|
152
|
+
def self.max_redirects
|
|
153
|
+
@max_redirects || 5
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Set maximum number of redirects
|
|
157
|
+
def self.max_redirects=(max_redirects)
|
|
158
|
+
unless max_redirects.nil? || (max_redirects.is_a?(Integer) && max_redirects >= 0)
|
|
159
|
+
fail ArgumentError, "max_redirects should be 0, a positive Integer or nil, got #{max_redirects}"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
@max_redirects = max_redirects
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Hook to call before making every request
|
|
166
|
+
def self.uri_checker
|
|
167
|
+
@uri_checker || proc{ |_uri| }
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Set hook to call before making every request
|
|
171
|
+
def self.uri_checker=(uri_checker)
|
|
172
|
+
unless uri_checker.nil? || uri_checker.respond_to?(:call)
|
|
173
|
+
fail ArgumentError, "uri_checker should respond to call or be nil, got #{uri_checker}"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
@uri_checker = uri_checker
|
|
177
|
+
end
|
|
127
178
|
end
|