httpthumbnailer 0.3.1 → 1.0.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.
- data/Gemfile +10 -11
- data/Gemfile.lock +75 -51
- data/README.md +184 -54
- data/VERSION +1 -1
- data/bin/httpthumbnailer +76 -133
- data/features/httpthumbnailer.feature +11 -260
- data/features/step_definitions/httpthumbnailer_steps.rb +89 -44
- data/features/support/env.rb +22 -9
- data/features/support/test-large.jpg +0 -0
- data/features/thumbnail.feature +241 -0
- data/features/thumbnails.feature +142 -0
- data/httpthumbnailer.gemspec +39 -40
- data/lib/httpthumbnailer/error_reporter.rb +38 -0
- data/lib/httpthumbnailer/plugin/thumbnailer.rb +396 -0
- data/lib/httpthumbnailer/thumbnail_specs.rb +50 -47
- data/lib/httpthumbnailer/thumbnailer.rb +52 -229
- data/load_test/load_test-cd9679c.csv +10 -0
- data/load_test/load_test-v0.3.1.csv +10 -0
- data/load_test/load_test.jmx +49 -34
- data/load_test/soak_test-ac0c6bcbe5e-broken-libjpeg-tatoos.csv +11 -0
- data/load_test/soak_test-cd9679c.csv +10 -0
- data/load_test/soak_test-f98334a-tatoos.csv +11 -0
- data/load_test/soak_test.jmx +697 -0
- data/spec/image_processing_spec.rb +148 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/thumbnail_specs_spec.rb +18 -5
- metadata +101 -71
- data/lib/httpthumbnailer/multipart_response.rb +0 -45
- data/spec/multipart_response_spec.rb +0 -95
- data/spec/thumbnailer_spec.rb +0 -33
data/bin/httpthumbnailer
CHANGED
@@ -1,151 +1,94 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
require 'cli'
|
4
|
-
require 'ip'
|
5
|
-
|
6
|
-
options = CLI.new do
|
7
|
-
description 'HTTP thumbnailing server'
|
8
|
-
switch :no_bind, :description => "Do not bind to TCP socket - useful with -s fastcgi option"
|
9
|
-
switch :no_logging, :description => "Disable logging"
|
10
|
-
switch :debug, :description => "Enable debugging"
|
11
|
-
switch :no_optimization, :description => "Disable size hinting and related optimization (loading, prescaling)"
|
12
|
-
option :bind, :short => :b, :default => IP.new('127.0.0.1'), :cast => IP, :description => "HTTP server bind address - use 0.0.0.0 to bind to all interfaces"
|
13
|
-
option :port, :short => :p, :default => 3100, :cast => Integer, :description => "HTTP server TCP port"
|
14
|
-
option :server, :short => :s, :default => 'mongrel', :description => "Rack server handler like thin, mongrel, webrick, fastcgi etc."
|
15
|
-
option :limit_memory, :default => 128*1024**2, :cast => Integer, :description => "Image cache heap memory size limit in bytes"
|
16
|
-
option :limit_map, :default => 256*1024**2, :cast => Integer, :description => "Image cache memory mapped file size limit in bytes - used when heap memory limit is used up"
|
17
|
-
option :limit_disk, :default => 0, :cast => Integer, :description => "Image cache temporary file size limit in bytes - used when memory mapped file limit is used up"
|
18
|
-
end.parse!
|
19
|
-
|
20
|
-
require 'sinatra/base'
|
21
|
-
require 'haml'
|
22
|
-
require 'RMagick'
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'unicorn-cuba-base'
|
23
3
|
|
24
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
25
|
-
require 'httpthumbnailer/thumbnailer'
|
26
|
-
require 'httpthumbnailer/thumbnail_specs'
|
27
|
-
|
28
|
-
sinatra = Sinatra.new
|
29
|
-
|
30
|
-
unless options.no_bind
|
31
|
-
sinatra.set :port, options.port
|
32
|
-
sinatra.set :bind, options.bind.to_s
|
33
|
-
else
|
34
|
-
sinatra.set :port, nil
|
35
|
-
sinatra.set :bind, nil
|
36
|
-
end
|
37
|
-
sinatra.set :environment, 'production'
|
38
|
-
sinatra.set :server, options.server
|
39
|
-
sinatra.set :lock, true
|
40
|
-
sinatra.set :boundary, "thumnail image data"
|
41
|
-
sinatra.set :logging, (not options.no_logging)
|
42
|
-
sinatra.set :debug, options.debug
|
43
|
-
sinatra.set :optimization, (not options.no_optimization)
|
44
|
-
sinatra.set :limit_memory, options.limit_memory
|
45
|
-
sinatra.set :limit_map, options.limit_map
|
46
|
-
sinatra.set :limit_disk, options.limit_disk
|
47
|
-
|
48
|
-
sinatra.before do
|
49
|
-
logger.level = Logger::DEBUG if settings.logging and settings.debug
|
50
|
-
if $thumbnailer.nil?
|
51
|
-
$thumbnailer = Thumbnailer.new(:logger => logger, :limit_memory => settings.limit_memory, :limit_map => settings.limit_map, :limit_disk => settings.limit_disk)
|
52
5
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
}.composite!(image, Magick::CenterGravity, Magick::OverCompositeOp)
|
67
|
-
|
68
|
-
image.destroy!
|
69
|
-
out
|
70
|
-
end
|
6
|
+
Application.new('httpthumbnailer', port: 3100) do
|
7
|
+
cli do
|
8
|
+
description 'Image thumbnailing HTTP server'
|
9
|
+
switch :formats,
|
10
|
+
short: :F,
|
11
|
+
description: 'print backend versions and supported formats'
|
12
|
+
option :limit_disk,
|
13
|
+
cast: Integer,
|
14
|
+
description: 'image cache temporary file size limit in MiB',
|
15
|
+
default: 1024
|
16
|
+
switch :no_optimization,
|
17
|
+
description: 'disable load time size hinting and prescaling optimizations'
|
18
|
+
version (Pathname.new(__FILE__).dirname + '..' + 'VERSION').read
|
71
19
|
end
|
72
|
-
end
|
73
20
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
21
|
+
settings do |settings|
|
22
|
+
if settings.formats
|
23
|
+
require 'httpthumbnailer/plugin/thumbnailer'
|
24
|
+
puts "Versions:"
|
25
|
+
puts "\t#{Plugin::Thumbnailer::Service.rmagick_version}"
|
26
|
+
puts "\t#{Plugin::Thumbnailer::Service.magick_version}"
|
27
|
+
puts
|
28
|
+
puts "Input formats:"
|
29
|
+
puts "\t#{Plugin::Thumbnailer::Service.input_formats.join(' ')}"
|
30
|
+
puts
|
31
|
+
puts "Output formats:"
|
32
|
+
puts "\t#{Plugin::Thumbnailer::Service.output_formats.join(' ')}"
|
33
|
+
exit 0
|
34
|
+
end
|
79
35
|
|
80
|
-
|
81
|
-
|
36
|
+
Controler.settings[:optimization] = (not settings.no_optimization)
|
37
|
+
Controler.settings[:limit_memory] = settings.limit_memory * 1024**2
|
38
|
+
Controler.settings[:limit_map] = settings.limit_disk * 1024**2
|
39
|
+
Controler.settings[:limit_disk] = settings.limit_disk * 1024**2
|
82
40
|
end
|
83
|
-
end
|
84
|
-
|
85
|
-
sinatra.get '/' do
|
86
|
-
logger.info 'hello'
|
87
|
-
end
|
88
|
-
|
89
|
-
sinatra.get '/stats/images' do
|
90
|
-
$thumbnailer.images.to_s
|
91
|
-
end
|
92
41
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
42
|
+
main do |settings|
|
43
|
+
require 'httpthumbnailer/error_reporter'
|
44
|
+
require 'httpthumbnailer/thumbnailer'
|
45
|
+
|
46
|
+
class HTTPThumbniler < Controler
|
47
|
+
extend Stats
|
48
|
+
def_stats(
|
49
|
+
:workers,
|
50
|
+
:total_requests,
|
51
|
+
:total_errors
|
52
|
+
)
|
53
|
+
|
54
|
+
raindrops_stats = Raindrops::Middleware::Stats.new
|
55
|
+
self.use Raindrops::Middleware, stats: raindrops_stats
|
56
|
+
|
57
|
+
StatsReporter << HTTPThumbniler.stats
|
58
|
+
StatsReporter << raindrops_stats
|
59
|
+
StatsReporter << Plugin::Thumbnailer::Service.stats
|
60
|
+
StatsReporter << Plugin::ResponseHelpers.stats
|
61
|
+
|
62
|
+
self.define do
|
63
|
+
HTTPThumbniler.stats.incr_total_requests
|
64
|
+
on error? do
|
65
|
+
HTTPThumbniler.stats.incr_total_errors
|
66
|
+
run ErrorReporter
|
67
|
+
end
|
68
|
+
|
69
|
+
on 'stats' do
|
70
|
+
run StatsReporter
|
71
|
+
end
|
100
72
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
headers "Content-Type" => "multipart/mixed; boundary=\"#{settings.boundary}\""
|
105
|
-
headers "X-Input-Image-Content-Type" => input_image.mime_type
|
73
|
+
on 'health_check' do
|
74
|
+
write_plain 200, 'OK'
|
75
|
+
end
|
106
76
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
logger.info "Thumbnailing: #{spec}"
|
111
|
-
out << "--#{settings.boundary}\r\n"
|
77
|
+
on root do
|
78
|
+
write_plain 200, 'HTTP Thumbnailer'
|
79
|
+
end
|
112
80
|
|
113
|
-
|
114
|
-
|
115
|
-
out << "Content-Type: #{thumbnail.mime_type}\r\n\r\n"
|
116
|
-
out << thumbnail.data
|
117
|
-
end
|
118
|
-
rescue => e
|
119
|
-
logger.error "Thumbnailing error: #{e.class.name}: #{e}: \n#{e.backtrace.join("\n")}"
|
120
|
-
out << "Content-Type: text/plain\r\n\r\n"
|
121
|
-
out << "Error: #{e.class.name}: #{e}\r\n"
|
122
|
-
ensure
|
123
|
-
out << "\r\n"
|
124
|
-
end
|
81
|
+
on true do
|
82
|
+
run Thumbnailer
|
125
83
|
end
|
126
|
-
out << "--#{settings.boundary}--"
|
127
84
|
end
|
128
85
|
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
sinatra.error Thumbnailer::UnsupportedMediaTypeError do
|
133
|
-
plain_exception(env['sinatra.error'])
|
134
|
-
halt 415
|
135
|
-
end
|
136
|
-
|
137
|
-
sinatra.error Thumbnailer::ImageTooLargeError do
|
138
|
-
plain_exception(env['sinatra.error'])
|
139
|
-
halt 413
|
140
|
-
end
|
141
86
|
|
142
|
-
|
143
|
-
|
144
|
-
end
|
87
|
+
HTTPThumbniler
|
88
|
+
end
|
145
89
|
|
146
|
-
|
147
|
-
|
90
|
+
after_fork do |server, worker|
|
91
|
+
HTTPThumbniler.stats.incr_workers
|
92
|
+
end
|
148
93
|
end
|
149
94
|
|
150
|
-
sinatra.run!
|
151
|
-
|
@@ -1,273 +1,24 @@
|
|
1
|
-
Feature:
|
2
|
-
|
3
|
-
A user must PUT an image to URL in format
|
4
|
-
/thumbnail[/<thumbnail type>,<width>,<height>,<format>[,<option key>:<option value>]+]+
|
1
|
+
Feature: HTTP server
|
2
|
+
It should behave like valid HTTP server
|
5
3
|
|
6
4
|
Background:
|
7
|
-
Given httpthumbnailer log is empty
|
8
5
|
Given httpthumbnailer server is running at http://localhost:3100/
|
9
6
|
|
10
|
-
Scenario: Single thumbnail
|
11
|
-
Given test.jpg file content as request body
|
12
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG
|
13
|
-
Then response status will be 200
|
14
|
-
And I will get multipart response
|
15
|
-
Then first part will contain PNG image of size 16x16
|
16
|
-
And first part mime type will be image/png
|
17
|
-
And there will be no leaked images
|
18
|
-
|
19
|
-
Scenario: Multiple thumbnails
|
20
|
-
Given test.jpg file content as request body
|
21
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG/crop,4,8,JPG/crop,16,32,JPEG
|
22
|
-
Then response status will be 200
|
23
|
-
And I will get multipart response
|
24
|
-
Then first part will contain PNG image of size 16x16
|
25
|
-
And first part mime type will be image/png
|
26
|
-
Then second part will contain JPEG image of size 4x8
|
27
|
-
And second part mime type will be image/jpeg
|
28
|
-
Then third part will contain JPEG image of size 16x32
|
29
|
-
And third part mime type will be image/jpeg
|
30
|
-
And there will be no leaked images
|
31
|
-
|
32
|
-
Scenario: Transparent image to JPEG handling - default background color white
|
33
|
-
Given test-transparent.png file content as request body
|
34
|
-
When I do PUT request http://localhost:3100/thumbnail/fit,128,128,JPEG
|
35
|
-
Then response status will be 200
|
36
|
-
And I will get multipart response
|
37
|
-
And first part body will be saved as test-transparent-default.png for human inspection
|
38
|
-
And first part will contain JPEG image of size 128x128
|
39
|
-
And that image pixel at 32x32 will be of color white
|
40
|
-
And there will be no leaked images
|
41
|
-
|
42
|
-
Scenario: Thumbnails of format INPUT should have same format as input image - for JPEG
|
43
|
-
Given test.jpg file content as request body
|
44
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG/crop,4,8,INPUT/crop,16,32,INPUT
|
45
|
-
Then response status will be 200
|
46
|
-
And I will get multipart response
|
47
|
-
Then first part will contain PNG image of size 16x16
|
48
|
-
And first part mime type will be image/png
|
49
|
-
Then second part will contain JPEG image of size 4x8
|
50
|
-
And second part mime type will be image/jpeg
|
51
|
-
Then third part will contain JPEG image of size 16x32
|
52
|
-
And third part mime type will be image/jpeg
|
53
|
-
|
54
|
-
Scenario: Thumbnails of format INPUT should have same format as input image - for PNG
|
55
|
-
Given test.png file content as request body
|
56
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,JPEG/crop,4,8,INPUT/crop,16,32,INPUT
|
57
|
-
Then response status will be 200
|
58
|
-
And I will get multipart response
|
59
|
-
Then first part will contain JPEG image of size 16x16
|
60
|
-
And first part mime type will be image/jpeg
|
61
|
-
Then second part will contain PNG image of size 4x8
|
62
|
-
And second part mime type will be image/png
|
63
|
-
Then third part will contain PNG image of size 16x32
|
64
|
-
And third part mime type will be image/png
|
65
|
-
|
66
|
-
Scenario: Thumbnails of width or height INPUT will have input image width or height
|
67
|
-
Given test.jpg file content as request body
|
68
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,INPUT,16,JPEG/crop,4,INPUT,PNG/crop,INPUT,INPUT,PNG
|
69
|
-
Then response status will be 200
|
70
|
-
And I will get multipart response
|
71
|
-
Then first part will contain JPEG image of size 509x16
|
72
|
-
And first part mime type will be image/jpeg
|
73
|
-
Then second part will contain PNG image of size 4x719
|
74
|
-
And second part mime type will be image/png
|
75
|
-
Then third part will contain PNG image of size 509x719
|
76
|
-
And third part mime type will be image/png
|
77
|
-
|
78
|
-
Scenario: Fit thumbnailing method
|
79
|
-
Given test.jpg file content as request body
|
80
|
-
When I do PUT request http://localhost:3100/thumbnail/fit,128,128,PNG
|
81
|
-
Then response status will be 200
|
82
|
-
And I will get multipart response
|
83
|
-
And first part will contain PNG image of size 91x128
|
84
|
-
And there will be no leaked images
|
85
|
-
|
86
|
-
Scenario: Pad thumbnailing method - default background color white
|
87
|
-
Given test.jpg file content as request body
|
88
|
-
When I do PUT request http://localhost:3100/thumbnail/pad,128,128,PNG
|
89
|
-
Then response status will be 200
|
90
|
-
And I will get multipart response
|
91
|
-
And first part body will be saved as test-pad.png for human inspection
|
92
|
-
And first part will contain PNG image of size 128x128
|
93
|
-
And that image pixel at 2x2 will be of color white
|
94
|
-
And there will be no leaked images
|
95
|
-
|
96
|
-
Scenario: Pad thumbnailing method with specified background color
|
97
|
-
Given test.jpg file content as request body
|
98
|
-
When I do PUT request http://localhost:3100/thumbnail/pad,128,128,PNG,background-color:green
|
99
|
-
Then response status will be 200
|
100
|
-
And I will get multipart response
|
101
|
-
And first part body will be saved as test-pad-background-color.png for human inspection
|
102
|
-
And first part will contain PNG image of size 128x128
|
103
|
-
And that image pixel at 2x2 will be of color green
|
104
|
-
And there will be no leaked images
|
105
|
-
|
106
|
-
Scenario: Image leaking on error
|
107
|
-
Given test.jpg file content as request body
|
108
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,0,0,PNG/fit,0,0,JPG/pad,0,0,JPEG
|
109
|
-
Then response status will be 200
|
110
|
-
And I will get multipart response
|
111
|
-
And first part content type will be text/plain
|
112
|
-
And second part content type will be text/plain
|
113
|
-
And third part content type will be text/plain
|
114
|
-
And there will be no leaked images
|
115
|
-
|
116
7
|
Scenario: Reporitng of missing resource for GET
|
117
8
|
When I do GET request http://localhost:3100/blah
|
118
|
-
Then response status
|
119
|
-
And response content type
|
120
|
-
And response body
|
9
|
+
Then response status should be 404
|
10
|
+
And response content type should be text/plain
|
11
|
+
And response body should be CRLF endend lines
|
121
12
|
"""
|
122
|
-
|
13
|
+
request for URI '/blah' was not handled by the server
|
123
14
|
"""
|
124
15
|
|
125
16
|
Scenario: Reporitng of missing resource for PUT
|
126
|
-
When I do PUT request http://localhost:3100/blah/
|
127
|
-
Then response status
|
128
|
-
And response content type
|
129
|
-
And response body
|
130
|
-
"""
|
131
|
-
Resource '/blah/thumbnail/crop,0,0,PNG/fit,0,0,JPG/pad,0,0,JPEG' not found
|
132
|
-
"""
|
133
|
-
|
134
|
-
Scenario: Reporitng of unsupported media type
|
135
|
-
Given test.txt file content as request body
|
136
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,128,128,PNG
|
137
|
-
Then response status will be 415
|
138
|
-
And response content type will be text/plain
|
139
|
-
And response body will be CRLF endend lines like
|
140
|
-
"""
|
141
|
-
Error: Thumbnailer::UnsupportedMediaTypeError: Magick::ImageMagickError:
|
142
|
-
"""
|
143
|
-
|
144
|
-
Scenario: Reporitng of bad thumbanil spec format - bad dimmension value
|
145
|
-
Given test.txt file content as request body
|
146
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,128,bogous,PNG
|
147
|
-
Then response status will be 500
|
148
|
-
And response content type will be text/plain
|
149
|
-
And response body will be CRLF endend lines
|
150
|
-
"""
|
151
|
-
Error: ThumbnailSpecs::BadThubnailSpecError::BadDimmensionValueError: bad dimmension value: bogous
|
152
|
-
"""
|
153
|
-
|
154
|
-
Scenario: Reporitng of bad thumbanil spec format - missing param
|
155
|
-
Given test.txt file content as request body
|
156
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,128,PNG
|
157
|
-
Then response status will be 500
|
158
|
-
And response content type will be text/plain
|
159
|
-
And response body will be CRLF endend lines
|
17
|
+
When I do PUT request http://localhost:3100/blah/thumbnails/crop,0,0,PNG/fit,0,0,JPG/pad,0,0,JPEG
|
18
|
+
Then response status should be 404
|
19
|
+
And response content type should be text/plain
|
20
|
+
And response body should be CRLF endend lines
|
160
21
|
"""
|
161
|
-
|
22
|
+
request for URI '/blah/thumbnails/crop,0,0,PNG/fit,0,0,JPG/pad,0,0,JPEG' was not handled by the server
|
162
23
|
"""
|
163
24
|
|
164
|
-
Scenario: Reporitng of bad thumbanil spec format - bad options format
|
165
|
-
Given test.txt file content as request body
|
166
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,128,128,PNG,fas-fda
|
167
|
-
Then response status will be 500
|
168
|
-
And response content type will be text/plain
|
169
|
-
And response body will be CRLF endend lines
|
170
|
-
"""
|
171
|
-
Error: ThumbnailSpecs::BadThubnailSpecError::MissingOptionKeyOrValueError: missing option key or value in: fas-fda
|
172
|
-
"""
|
173
|
-
|
174
|
-
Scenario: Reporitng of image thumbnailing errors
|
175
|
-
Given test.jpg file content as request body
|
176
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG/crop,0,0,JPG/crop,16,32,JPEG
|
177
|
-
Then response status will be 200
|
178
|
-
And I will get multipart response
|
179
|
-
Then first part will contain PNG image of size 16x16
|
180
|
-
And first part mime type will be image/png
|
181
|
-
And second part content type will be text/plain
|
182
|
-
And second part body will be CRLF endend lines
|
183
|
-
"""
|
184
|
-
Error: ArgumentError: invalid result dimension (0, 0 given)
|
185
|
-
"""
|
186
|
-
Then third part will contain JPEG image of size 16x32
|
187
|
-
And third part mime type will be image/jpeg
|
188
|
-
And there will be no leaked images
|
189
|
-
|
190
|
-
Scenario: Handing of large image data - possible thanks to loading size optimization
|
191
|
-
Given test-large.jpg file content as request body
|
192
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG/crop,32,32,JPEG
|
193
|
-
Then response status will be 200
|
194
|
-
And I will get multipart response
|
195
|
-
Then first part will contain PNG image of size 16x16
|
196
|
-
And first part mime type will be image/png
|
197
|
-
Then second part will contain JPEG image of size 32x32
|
198
|
-
And second part mime type will be image/jpeg
|
199
|
-
And there will be no leaked images
|
200
|
-
|
201
|
-
Scenario: Memory limits exhausted while loading
|
202
|
-
Given test-large.jpg file content as request body
|
203
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,7000,7000,PNG
|
204
|
-
Then response status will be 413
|
205
|
-
And response content type will be text/plain
|
206
|
-
And response body will be CRLF endend lines like
|
207
|
-
"""
|
208
|
-
Error: Thumbnailer::ImageTooLargeError: Magick::ImageMagickError: cache resources exhausted
|
209
|
-
"""
|
210
|
-
And there will be no leaked images
|
211
|
-
|
212
|
-
Scenario: Memory limits exhausted while thumbnailing
|
213
|
-
Given test.jpg file content as request body
|
214
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG/crop,16000,16000,JPG/crop,16,32,JPEG
|
215
|
-
Then response status will be 200
|
216
|
-
And I will get multipart response
|
217
|
-
Then first part will contain PNG image of size 16x16
|
218
|
-
And first part mime type will be image/png
|
219
|
-
And second part content type will be text/plain
|
220
|
-
And second part body will be CRLF endend lines like
|
221
|
-
"""
|
222
|
-
Error: Thumbnailer::ImageTooLargeError: Magick::ImageMagickError: cache resources exhausted
|
223
|
-
"""
|
224
|
-
Then third part will contain JPEG image of size 16x32
|
225
|
-
And third part mime type will be image/jpeg
|
226
|
-
And there will be no leaked images
|
227
|
-
|
228
|
-
Scenario: Quality option - JPEG
|
229
|
-
Given test.jpg file content as request body
|
230
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,32,32,JPEG,quality:10/crop,32,32,JPG,quality:80/crop,32,32,JPEG,quality:90
|
231
|
-
Then response status will be 200
|
232
|
-
And I will get multipart response
|
233
|
-
And first part mime type will be image/jpeg
|
234
|
-
And second part mime type will be image/jpeg
|
235
|
-
And third part mime type will be image/jpeg
|
236
|
-
Then first part will contain body smaller than second part
|
237
|
-
Then second part will contain body smaller than third part
|
238
|
-
|
239
|
-
Scenario: Quality option - JPEG - default 85
|
240
|
-
Given test.jpg file content as request body
|
241
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,32,32,JPEG,quality:84/crop,32,32,JPG/crop,32,32,JPEG,quality:86
|
242
|
-
Then response status will be 200
|
243
|
-
And I will get multipart response
|
244
|
-
And first part mime type will be image/jpeg
|
245
|
-
And second part mime type will be image/jpeg
|
246
|
-
And third part mime type will be image/jpeg
|
247
|
-
Then first part will contain body smaller than second part
|
248
|
-
Then second part will contain body smaller than third part
|
249
|
-
|
250
|
-
Scenario: Quality option - PNG (XY where X - zlib compresion level, Y - filter)
|
251
|
-
Given test.jpg file content as request body
|
252
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,64,64,PNG,quality:90/crop,64,64,PNG,quality:50/crop,64,64,PNG,quality:10
|
253
|
-
Then response status will be 200
|
254
|
-
And I will get multipart response
|
255
|
-
And first part mime type will be image/png
|
256
|
-
And second part mime type will be image/png
|
257
|
-
And third part mime type will be image/png
|
258
|
-
Then first part will contain body smaller than second part
|
259
|
-
Then second part will contain body smaller than third part
|
260
|
-
And there will be no leaked images
|
261
|
-
|
262
|
-
Scenario: Hint on input image mime type - JPEG
|
263
|
-
Given test.jpg file content as request body
|
264
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG
|
265
|
-
Then response status will be 200
|
266
|
-
And X-Input-Image-Content-Type header will be image/jpeg
|
267
|
-
|
268
|
-
Scenario: Hint on input image mime type - PNG
|
269
|
-
Given test.png file content as request body
|
270
|
-
When I do PUT request http://localhost:3100/thumbnail/crop,16,16,PNG
|
271
|
-
Then response status will be 200
|
272
|
-
And X-Input-Image-Content-Type header will be image/png
|
273
|
-
|