image_vise 0.0.20 → 0.0.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/image_vise.gemspec +5 -3
- data/lib/image_vise/render_engine.rb +22 -9
- data/lib/image_vise.rb +1 -1
- data/spec/image_vise/render_engine_spec.rb +69 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/waterside_magic_hour.psd +0 -0
- data/spec/waterside_magic_hour_gray.tif +0 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a79d07f95e9fcf0800a432a49420da6d856ee52
|
4
|
+
data.tar.gz: 5bd849b46ac06048071bbad834e9bf2a396f902e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ab89461f69e6efb15e776f73dfcd1fc85346b8744cce1d0b9b2df28bd44cb75f0a23bb12e6be61394609cbe60354d64ad04b4124c941f1ac26770e5c5f5d684
|
7
|
+
data.tar.gz: 24fd679469621e2c2e03c039e22185fde97e931bc2883a9c3dc8c5733e376363fa78c4ce21ed970559b6173efc492a821e7a266079ab7666bd359bb43c1ac7c2
|
data/image_vise.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
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.0.
|
5
|
+
# stub: image_vise 0.0.21 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "image_vise"
|
9
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.21"
|
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"]
|
@@ -55,7 +55,9 @@ Gem::Specification.new do |s|
|
|
55
55
|
"spec/spec_helper.rb",
|
56
56
|
"spec/test_server.rb",
|
57
57
|
"spec/waterside_magic_hour.jpg",
|
58
|
-
"spec/
|
58
|
+
"spec/waterside_magic_hour.psd",
|
59
|
+
"spec/waterside_magic_hour_adobergb.jpg",
|
60
|
+
"spec/waterside_magic_hour_gray.tif"
|
59
61
|
]
|
60
62
|
s.homepage = "https://github.com/WeTransfer/image_vise"
|
61
63
|
s.licenses = ["MIT"]
|
@@ -18,10 +18,14 @@ class ImageVise::RenderEngine
|
|
18
18
|
# How long is a render (the ImageMagick/write part) is allowed to
|
19
19
|
# take before we kill it
|
20
20
|
RENDER_TIMEOUT_SECONDS = 10
|
21
|
-
|
21
|
+
|
22
22
|
# Which input files we permit (based on extensions stored in MagicBytes)
|
23
|
-
|
24
|
-
|
23
|
+
PERMITTED_SOURCE_FILE_EXTENSIONS = %w( gif png jpg )
|
24
|
+
|
25
|
+
# Which output files are permitted (regardless of the input format
|
26
|
+
# the processed images will be converted to one of these types)
|
27
|
+
PERMITTED_OUTPUT_FILE_EXTENSIONS = %W( gif png jpg)
|
28
|
+
|
25
29
|
# How long should we wait when fetching the image from the external host
|
26
30
|
EXTERNAL_IMAGE_FETCH_TIMEOUT_SECONDS = 4
|
27
31
|
|
@@ -81,6 +85,9 @@ class ImageVise::RenderEngine
|
|
81
85
|
|
82
86
|
# Make sure we do not try to process something...questionable
|
83
87
|
source_file_type = detect_file_type(source_file)
|
88
|
+
unless source_file_type_permitted?(source_file_type)
|
89
|
+
raise UnsupportedInputFormat.new("Unsupported/unknown input file format .%s" % source_file_type.ext)
|
90
|
+
end
|
84
91
|
|
85
92
|
# Perform the processing
|
86
93
|
if enable_forking?
|
@@ -136,13 +143,17 @@ class ImageVise::RenderEngine
|
|
136
143
|
|
137
144
|
def detect_file_type(tempfile)
|
138
145
|
tempfile.rewind
|
139
|
-
|
140
|
-
file_info = MagicBytes.read_and_detect(tempfile)
|
141
|
-
return file_info if PERMITTED_EXTENSIONS.include?(file_info.ext)
|
142
|
-
raise UnsupportedInputFormat.new("Unsupported/unknown input file format .%s" %
|
143
|
-
file_info.ext)
|
146
|
+
MagicBytes.read_and_detect(tempfile)
|
144
147
|
end
|
145
|
-
|
148
|
+
|
149
|
+
def source_file_type_permitted?(magick_bytes_file_info)
|
150
|
+
PERMITTED_SOURCE_FILE_EXTENSIONS.include?(magick_bytes_file_info.ext)
|
151
|
+
end
|
152
|
+
|
153
|
+
def output_file_type_permitted?(magick_bytes_file_info)
|
154
|
+
PERMITTED_OUTPUT_FILE_EXTENSIONS.include?(magick_bytes_file_info.ext)
|
155
|
+
end
|
156
|
+
|
146
157
|
# Lists exceptions that should lead to the request being flagged
|
147
158
|
# as invalid (and not 5xx). Decent clients should _not_ retry those requests.
|
148
159
|
def permanent_failures
|
@@ -188,6 +199,7 @@ class ImageVise::RenderEngine
|
|
188
199
|
# If processing the image has created an alpha channel, use PNG always.
|
189
200
|
# Otherwise, keep the original format for as far as the supported formats list goes.
|
190
201
|
render_file_type = PNG_FILE_TYPE if magick_image.alpha?
|
202
|
+
render_file_type = PNG_FILE_TYPE unless output_file_type_permitted?(render_file_type)
|
191
203
|
|
192
204
|
magick_image.format = render_file_type.ext
|
193
205
|
magick_image.write(render_to_path)
|
@@ -227,6 +239,7 @@ class ImageVise::RenderEngine
|
|
227
239
|
end
|
228
240
|
tf.rewind; tf
|
229
241
|
rescue Errno::ENOENT
|
242
|
+
tf.close; tf.unlink;
|
230
243
|
bail 404, "Image file not found"
|
231
244
|
rescue Exception => e
|
232
245
|
tf.close; tf.unlink;
|
data/lib/image_vise.rb
CHANGED
@@ -209,5 +209,74 @@ describe ImageVise::RenderEngine do
|
|
209
209
|
|
210
210
|
examine_image_from_string(last_response.body)
|
211
211
|
end
|
212
|
+
|
213
|
+
it 'forbids a PSD file by default' do
|
214
|
+
uri = Addressable::URI.parse(public_url_psd)
|
215
|
+
ImageVise.add_allowed_host!(uri.host)
|
216
|
+
ImageVise.add_secret_key!('l33tness')
|
217
|
+
|
218
|
+
p = ImageVise::Pipeline.new.geom(geometry_string: '220x220').ellipse_stencil
|
219
|
+
image_request = ImageVise::ImageRequest.new(src_url: uri.to_s, pipeline: p)
|
220
|
+
params = image_request.to_query_string_params('l33tness')
|
221
|
+
|
222
|
+
get '/', params
|
223
|
+
expect(last_response.status).to eq(422)
|
224
|
+
expect(last_response.body).to include('unknown input file format .psd')
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'permits a PSD file if it is permitted via a method override' do
|
228
|
+
uri = Addressable::URI.parse(public_url_psd)
|
229
|
+
ImageVise.add_allowed_host!(uri.host)
|
230
|
+
ImageVise.add_secret_key!('l33tness')
|
231
|
+
|
232
|
+
p = ImageVise::Pipeline.new.geom(geometry_string: '220x220')
|
233
|
+
image_request = ImageVise::ImageRequest.new(src_url: uri.to_s, pipeline: p)
|
234
|
+
params = image_request.to_query_string_params('l33tness')
|
235
|
+
|
236
|
+
class << app
|
237
|
+
def source_file_type_permitted?(type); true; end
|
238
|
+
end
|
239
|
+
|
240
|
+
get '/', params
|
241
|
+
expect(last_response.status).to eq(200)
|
242
|
+
expect(last_response.headers['Content-Type']).to eq('image/png')
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'outputs a converted TIFF file as a PNG' do
|
246
|
+
uri = Addressable::URI.parse(public_url_tif)
|
247
|
+
ImageVise.add_allowed_host!(uri.host)
|
248
|
+
ImageVise.add_secret_key!('l33tness')
|
249
|
+
|
250
|
+
p = ImageVise::Pipeline.new.geom(geometry_string: '220x220')
|
251
|
+
image_request = ImageVise::ImageRequest.new(src_url: uri.to_s, pipeline: p)
|
252
|
+
params = image_request.to_query_string_params('l33tness')
|
253
|
+
|
254
|
+
class << app
|
255
|
+
def source_file_type_permitted?(type); true; end
|
256
|
+
end
|
257
|
+
|
258
|
+
get '/', params
|
259
|
+
expect(last_response.status).to eq(200)
|
260
|
+
expect(last_response.headers['Content-Type']).to eq('image/png')
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'outputs a converted TIFF file in the TIFF format if it is on the permitted list' do
|
264
|
+
uri = Addressable::URI.parse(public_url_tif)
|
265
|
+
ImageVise.add_allowed_host!(uri.host)
|
266
|
+
ImageVise.add_secret_key!('l33tness')
|
267
|
+
|
268
|
+
p = ImageVise::Pipeline.new.geom(geometry_string: '220x220')
|
269
|
+
image_request = ImageVise::ImageRequest.new(src_url: uri.to_s, pipeline: p)
|
270
|
+
params = image_request.to_query_string_params('l33tness')
|
271
|
+
|
272
|
+
class << app
|
273
|
+
def source_file_type_permitted?(type); true; end
|
274
|
+
def output_file_type_permitted?(type); true; end
|
275
|
+
end
|
276
|
+
|
277
|
+
get '/', params
|
278
|
+
expect(last_response.status).to eq(200)
|
279
|
+
expect(last_response.headers['Content-Type']).to eq('image/tiff')
|
280
|
+
end
|
212
281
|
end
|
213
282
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -64,6 +64,14 @@ RSpec.configure do | config |
|
|
64
64
|
File.expand_path(__dir__ + '/waterside_magic_hour.jpg')
|
65
65
|
end
|
66
66
|
|
67
|
+
def test_image_path_psd
|
68
|
+
File.expand_path(__dir__ + '/waterside_magic_hour.psd')
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_image_path_tif
|
72
|
+
File.expand_path(__dir__ + '/waterside_magic_hour_gray.tif')
|
73
|
+
end
|
74
|
+
|
67
75
|
def test_image_adobergb_path
|
68
76
|
File.expand_path(__dir__ + '/waterside_magic_hour_adobergb.jpg')
|
69
77
|
end
|
@@ -72,6 +80,14 @@ RSpec.configure do | config |
|
|
72
80
|
'http://localhost:9001/waterside_magic_hour.jpg'
|
73
81
|
end
|
74
82
|
|
83
|
+
def public_url_psd
|
84
|
+
'http://localhost:9001/waterside_magic_hour.psd'
|
85
|
+
end
|
86
|
+
|
87
|
+
def public_url_tif
|
88
|
+
'http://localhost:9001/waterside_magic_hour_gray.tif'
|
89
|
+
end
|
90
|
+
|
75
91
|
config.around :each do |e|
|
76
92
|
STRICT_ENV.with_protected_env { e.run }
|
77
93
|
end
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_vise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
@@ -284,7 +284,9 @@ files:
|
|
284
284
|
- spec/spec_helper.rb
|
285
285
|
- spec/test_server.rb
|
286
286
|
- spec/waterside_magic_hour.jpg
|
287
|
+
- spec/waterside_magic_hour.psd
|
287
288
|
- spec/waterside_magic_hour_adobergb.jpg
|
289
|
+
- spec/waterside_magic_hour_gray.tif
|
288
290
|
homepage: https://github.com/WeTransfer/image_vise
|
289
291
|
licenses:
|
290
292
|
- MIT
|