image_vise 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/DEVELOPMENT.md +26 -2
- data/README.md +0 -11
- data/image_vise.gemspec +5 -3
- data/lib/image_vise/fetchers/fetcher_file.rb +1 -1
- data/lib/image_vise/fetchers/fetcher_http.rb +2 -3
- data/lib/image_vise/file_response.rb +1 -1
- data/lib/image_vise.rb +1 -1
- data/spec/image_vise/fetcher_file_spec.rb +48 -0
- data/spec/image_vise/fetcher_http_spec.rb +44 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8fd6c51aedf4fe76ee330a75a0a967da91397452
|
4
|
+
data.tar.gz: 7ce66027f5c46d4812591884efea60047ceefca7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5ef54f0cd31ebde260bcb9f580dabf303e3bf10a9b451bea1eb0999a89cb71c3b8a55124bb86313fbaba4f5f25143250fabaf78318758f6426fb8c4a8a43a6c
|
7
|
+
data.tar.gz: ccd3a779a38de87d4f7e35c9d11cebeef2b8c748a3fbd5331716c749f1e7d4d223ace28bc352ba5b7447630b85330ee030fd229b3b0784b34f8e1ccdd257a214
|
data/DEVELOPMENT.md
CHANGED
@@ -55,7 +55,20 @@ it:
|
|
55
55
|
|
56
56
|
ImageVise.register_fetcher 'profilepictures', self
|
57
57
|
|
58
|
-
Once done, you can use URLs like `profilepictures:/5674
|
58
|
+
Once done, you can use URLs like `profilepictures:/5674`. A very simple Fetcher would just
|
59
|
+
override the standard filesystem one (be mindful that the filesystem fetcher still checks
|
60
|
+
path access using the glob whitelist)
|
61
|
+
|
62
|
+
class PicFetcher < ImageVise::FetcherFile
|
63
|
+
def self.fetch_uri_to_tempfile(uri_object)
|
64
|
+
# Convert an internal "pic://sites/uploads/abcdef.jpg" to a full path URL
|
65
|
+
partial_path = URI.decode(uri_object.path)
|
66
|
+
full_path = File.join(Mappe::ROOT, 'sites', partial_path)
|
67
|
+
full_path_uri = URI('file://' + URI.encode(full_path))
|
68
|
+
super(full_path_uri)
|
69
|
+
end
|
70
|
+
ImageVise.register_fetcher 'pic', self
|
71
|
+
end
|
59
72
|
|
60
73
|
## Overriding the render engine
|
61
74
|
|
@@ -95,4 +108,15 @@ actually using them. If you are using a library it is a one-time cost, with very
|
|
95
108
|
|
96
109
|
Also note that image operators are not per definition Imagemagick-specific - it's completely possible to not only use
|
97
110
|
a different library for processing them, but even to use a different image processing server complying to the
|
98
|
-
same protocol (a signed JSON-encodded waybill of HTTP(S) source-URL + pipeline instructions).
|
111
|
+
same protocol (a signed JSON-encodded waybill of HTTP(S) source-URL + pipeline instructions).
|
112
|
+
|
113
|
+
## Using forked child processes for RMagick tasks
|
114
|
+
|
115
|
+
You can optionally set the `IMAGE_VISE_ENABLE_FORK` environment variable to `yes` to enable forking. When this
|
116
|
+
variable is set, ImageVise will fork a child process and perform the image processing task within that process,
|
117
|
+
killing it afterwards and deallocating all the memory. This can be extremely efficient for dealing with potential
|
118
|
+
memory bloat issues in ImageMagick/RMagick. However, loading images into RMagick may hang in a forked child. This
|
119
|
+
will lead to the child being timeout-terminated, and no image is going to be rendered. This issue is known and
|
120
|
+
also platform-dependent (it does not happen on OSX but does happen on Docker within Ubuntu Trusty for instance).
|
121
|
+
|
122
|
+
So, this feature _does_ exist but your mileage may vary with regards to it's use.
|
data/README.md
CHANGED
@@ -176,17 +176,6 @@ within a machine-readable JSON payload. If that doesn't work for you, or you wan
|
|
176
176
|
handling using some error tracking provider, either subclass `ImageVise::RenderEngine` or prepend
|
177
177
|
a module into it that will intercept the errors. See error handling in `examples/` for more.
|
178
178
|
|
179
|
-
## Using forked child processes for RMagick tasks
|
180
|
-
|
181
|
-
You can optionally set the `IMAGE_VISE_ENABLE_FORK` environment variable to `yes` to enable forking. When this
|
182
|
-
variable is set, ImageVise will fork a child process and perform the image processing task within that process,
|
183
|
-
killing it afterwards and deallocating all the memory. This can be extremely efficient for dealing with potential
|
184
|
-
memory bloat issues in ImageMagick/RMagick. However, loading images into RMagick may hang in a forked child. This
|
185
|
-
will lead to the child being timeout-terminated, and no image is going to be rendered. This issue is known and
|
186
|
-
also platform-dependent (it does not happen on OSX but does happen on Docker within Ubuntu Trusty for instance).
|
187
|
-
|
188
|
-
So, this feature _does_ exist but your mileage may vary with regards to it's use.
|
189
|
-
|
190
179
|
## State
|
191
180
|
|
192
181
|
Except for the HTTP cache no state is stored (`ImageVise` does not care whether you store
|
data/image_vise.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: image_vise 0.1.
|
5
|
+
# stub: image_vise 0.1.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "image_vise"
|
9
|
-
s.version = "0.1.
|
9
|
+
s.version = "0.1.1"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Julik Tarkhanov"]
|
14
|
-
s.date = "2016-10-
|
14
|
+
s.date = "2016-10-22"
|
15
15
|
s.description = "Image processing via URLs"
|
16
16
|
s.email = "me@julik.nl"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -49,6 +49,8 @@ Gem::Specification.new do |s|
|
|
49
49
|
"spec/image_vise/auto_orient_spec.rb",
|
50
50
|
"spec/image_vise/crop_spec.rb",
|
51
51
|
"spec/image_vise/ellipse_stencil_spec.rb",
|
52
|
+
"spec/image_vise/fetcher_file_spec.rb",
|
53
|
+
"spec/image_vise/fetcher_http_spec.rb",
|
52
54
|
"spec/image_vise/file_response_spec.rb",
|
53
55
|
"spec/image_vise/fit_crop_spec.rb",
|
54
56
|
"spec/image_vise/geom_spec.rb",
|
@@ -20,7 +20,7 @@ class ImageVise::FetcherFile
|
|
20
20
|
patterns = ImageVise.allowed_filesystem_sources
|
21
21
|
matches = patterns.any? { |glob_pattern| File.fnmatch?(glob_pattern, path_on_filesystem) }
|
22
22
|
raise AccessError, "filesystem access is disabled" unless patterns.any?
|
23
|
-
raise AccessError, "#{
|
23
|
+
raise AccessError, "#{path_on_filesystem} is not on the path whitelist" unless matches
|
24
24
|
end
|
25
25
|
|
26
26
|
ImageVise.register_fetcher 'file', self
|
@@ -33,9 +33,8 @@ class ImageVise::FetcherHTTP
|
|
33
33
|
|
34
34
|
def self.verify_uri_access!(uri)
|
35
35
|
host = uri.host
|
36
|
-
|
37
|
-
|
38
|
-
end
|
36
|
+
return if ImageVise.allowed_hosts.include?(uri.host)
|
37
|
+
raise AccessError, "#{uri} is not permitted as source"
|
39
38
|
end
|
40
39
|
|
41
40
|
ImageVise.register_fetcher 'http', self
|
data/lib/image_vise.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe ImageVise::FetcherFile do
|
4
|
+
it 'is a class (can be inherited from)' do
|
5
|
+
expect(ImageVise::FetcherFile).to be_kind_of(Class)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'is registered as a fetcher for file://' do
|
9
|
+
expect(ImageVise.fetcher_for('file')).to eq(ImageVise::FetcherFile)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns a Tempfile containing this test suite' do
|
13
|
+
path = File.expand_path(__FILE__)
|
14
|
+
ruby_files_in_this_directory = __dir__ + '/*.rb'
|
15
|
+
ImageVise.allow_filesystem_source! ruby_files_in_this_directory
|
16
|
+
|
17
|
+
uri = URI('file://' + URI.encode(path))
|
18
|
+
fetched = ImageVise::FetcherFile.fetch_uri_to_tempfile(uri)
|
19
|
+
|
20
|
+
expect(fetched).to be_kind_of(Tempfile)
|
21
|
+
expect(fetched.size).to eq(File.size(__FILE__))
|
22
|
+
expect(fetched.pos).to be_zero
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'raises a meaningful exception if no file sources are permitted' do
|
26
|
+
path = File.expand_path(__FILE__)
|
27
|
+
|
28
|
+
ImageVise.deny_filesystem_sources!
|
29
|
+
|
30
|
+
uri = URI('file://' + URI.encode(path))
|
31
|
+
expect {
|
32
|
+
ImageVise::FetcherFile.fetch_uri_to_tempfile(uri)
|
33
|
+
}.to raise_error(ImageVise::FetcherFile::AccessError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'raises a meaningful exception if this file is not permitted as source' do
|
37
|
+
path = File.expand_path(__FILE__)
|
38
|
+
|
39
|
+
text_files_in_this_directory = __dir__ + '/*.txt'
|
40
|
+
ImageVise.deny_filesystem_sources!
|
41
|
+
ImageVise.allow_filesystem_source! text_files_in_this_directory
|
42
|
+
|
43
|
+
uri = URI('file://' + URI.encode(path))
|
44
|
+
expect {
|
45
|
+
ImageVise::FetcherFile.fetch_uri_to_tempfile(uri)
|
46
|
+
}.to raise_error(ImageVise::FetcherFile::AccessError)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe ImageVise::FetcherHTTP do
|
4
|
+
it 'is a class (can be inherited from)' do
|
5
|
+
expect(ImageVise::FetcherHTTP).to be_kind_of(Class)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'is registered as a fetcher for http:// and https://' do
|
9
|
+
expect(ImageVise.fetcher_for('http')).to eq(ImageVise::FetcherHTTP)
|
10
|
+
expect(ImageVise.fetcher_for('https')).to eq(ImageVise::FetcherHTTP)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'raises an AccessError if the host of the URL is not on the whitelist' do
|
14
|
+
uri = URI('https://wrong-origin.com/image.psd')
|
15
|
+
expect {
|
16
|
+
ImageVise::FetcherHTTP.fetch_uri_to_tempfile(uri)
|
17
|
+
}.to raise_error(ImageVise::FetcherHTTP::AccessError, /is not permitted as source/)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises an UpstreamError if the upstream fetch returns an error-ish status code' do
|
21
|
+
uri = URI('http://localhost:9001/forbidden')
|
22
|
+
ImageVise.add_allowed_host! 'localhost'
|
23
|
+
|
24
|
+
expect {
|
25
|
+
ImageVise::FetcherHTTP.fetch_uri_to_tempfile(uri)
|
26
|
+
}.to raise_error {|e|
|
27
|
+
expect(e).to be_kind_of(ImageVise::FetcherHTTP::UpstreamError)
|
28
|
+
expect(e.message).to include(uri.to_s)
|
29
|
+
expect(e.message).to include('403')
|
30
|
+
expect(e.http_status).to eq(403)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'fetches the image into a Tempfile' do
|
35
|
+
uri = URI(public_url_psd)
|
36
|
+
ImageVise.add_allowed_host! 'localhost'
|
37
|
+
|
38
|
+
result = ImageVise::FetcherHTTP.fetch_uri_to_tempfile(uri)
|
39
|
+
|
40
|
+
expect(result).to be_kind_of(Tempfile)
|
41
|
+
expect(result.size).to be_nonzero
|
42
|
+
expect(result.pos).to be_zero
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_vise
|
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
|
- Julik Tarkhanov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: patron
|
@@ -292,6 +292,8 @@ files:
|
|
292
292
|
- spec/image_vise/auto_orient_spec.rb
|
293
293
|
- spec/image_vise/crop_spec.rb
|
294
294
|
- spec/image_vise/ellipse_stencil_spec.rb
|
295
|
+
- spec/image_vise/fetcher_file_spec.rb
|
296
|
+
- spec/image_vise/fetcher_http_spec.rb
|
295
297
|
- spec/image_vise/file_response_spec.rb
|
296
298
|
- spec/image_vise/fit_crop_spec.rb
|
297
299
|
- spec/image_vise/geom_spec.rb
|