httpthumbnailer 0.3.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|