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
 
| 
         @@ -1,247 +1,70 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require ' 
     | 
| 
      
 1 
     | 
    
         
            +
            require 'httpthumbnailer/plugin/thumbnailer'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'httpthumbnailer/thumbnail_specs'
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            class  
     | 
| 
       4 
     | 
    
         
            -
            	 
     | 
| 
       5 
     | 
    
         
            -
            		Thumbnailer::ImageHandler.new do
         
     | 
| 
       6 
     | 
    
         
            -
            			self
         
     | 
| 
       7 
     | 
    
         
            -
            		end.use do |image|
         
     | 
| 
       8 
     | 
    
         
            -
            			Magick::Image.new(image.columns, image.rows) {
         
     | 
| 
       9 
     | 
    
         
            -
            				self.background_color = background_color
         
     | 
| 
       10 
     | 
    
         
            -
            			}.composite!(image, Magick::CenterGravity, Magick::OverCompositeOp)
         
     | 
| 
       11 
     | 
    
         
            -
            		end
         
     | 
| 
       12 
     | 
    
         
            -
            	end
         
     | 
| 
       13 
     | 
    
         
            -
            end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            class Thumbnailer
         
     | 
| 
       16 
     | 
    
         
            -
            	class UnsupportedMethodError < ArgumentError
         
     | 
| 
       17 
     | 
    
         
            -
            		def initialize(method)
         
     | 
| 
       18 
     | 
    
         
            -
            			super("Thumbnail method '#{method}' is not supported")
         
     | 
| 
       19 
     | 
    
         
            -
            		end
         
     | 
| 
       20 
     | 
    
         
            -
            	end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            	class UnsupportedMediaTypeError < ArgumentError
         
     | 
| 
       23 
     | 
    
         
            -
            		def initialize(e)
         
     | 
| 
       24 
     | 
    
         
            -
            			super("#{e.class.name}: #{e}")
         
     | 
| 
       25 
     | 
    
         
            -
            		end
         
     | 
| 
       26 
     | 
    
         
            -
            	end
         
     | 
| 
      
 4 
     | 
    
         
            +
            class Thumbnailer < Controler
         
     | 
| 
      
 5 
     | 
    
         
            +
            	self.plugin Plugin::Thumbnailer
         
     | 
| 
       27 
6 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
            	 
     | 
| 
       29 
     | 
    
         
            -
            		 
     | 
| 
       30 
     | 
    
         
            -
            			 
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
            	end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
            	class ImageHandler
         
     | 
| 
       35 
     | 
    
         
            -
            		class ImageDestroyedError < RuntimeError
         
     | 
| 
       36 
     | 
    
         
            -
            			def initialize
         
     | 
| 
       37 
     | 
    
         
            -
            				super("image was already used")
         
     | 
| 
       38 
     | 
    
         
            -
            			end
         
     | 
| 
       39 
     | 
    
         
            -
            		end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            		def initialize
         
     | 
| 
       42 
     | 
    
         
            -
            			@image = yield
         
     | 
| 
       43 
     | 
    
         
            -
            		end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
            		def get
         
     | 
| 
       46 
     | 
    
         
            -
            			raise ImageDestroyedError unless @image
         
     | 
| 
       47 
     | 
    
         
            -
            			begin
         
     | 
| 
       48 
     | 
    
         
            -
            				yield @image
         
     | 
| 
       49 
     | 
    
         
            -
            			rescue
         
     | 
| 
       50 
     | 
    
         
            -
            				@image.destroy!
         
     | 
| 
       51 
     | 
    
         
            -
            				@image = nil
         
     | 
| 
       52 
     | 
    
         
            -
            				raise
         
     | 
| 
       53 
     | 
    
         
            -
            			end
         
     | 
| 
       54 
     | 
    
         
            -
            		end
         
     | 
| 
      
 7 
     | 
    
         
            +
            	self.define do
         
     | 
| 
      
 8 
     | 
    
         
            +
            		on put, 'thumbnail', /(.*)/ do |spec|
         
     | 
| 
      
 9 
     | 
    
         
            +
            			spec = ThumbnailSpec.from_uri(spec)
         
     | 
| 
      
 10 
     | 
    
         
            +
            			log.info "thumbnailing image to single spec: #{spec}"
         
     | 
| 
       55 
11 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
            			 
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
            				 
     | 
| 
       60 
     | 
    
         
            -
            			ensure
         
     | 
| 
       61 
     | 
    
         
            -
            				@image.destroy!
         
     | 
| 
       62 
     | 
    
         
            -
            				@image = nil
         
     | 
| 
      
 12 
     | 
    
         
            +
            			opts = {}
         
     | 
| 
      
 13 
     | 
    
         
            +
            			if settings[:optimization]
         
     | 
| 
      
 14 
     | 
    
         
            +
            				opts['max-width'] = spec.width if spec.width.is_a? Integer
         
     | 
| 
      
 15 
     | 
    
         
            +
            				opts['max-height'] = spec.height if spec.height.is_a? Integer
         
     | 
| 
       63 
16 
     | 
    
         
             
            			end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
            		def destroy!
         
     | 
| 
       67 
     | 
    
         
            -
            			return unless @image
         
     | 
| 
       68 
     | 
    
         
            -
            			@image.destroy!
         
     | 
| 
       69 
     | 
    
         
            -
            			@image = nil
         
     | 
| 
       70 
     | 
    
         
            -
            		end
         
     | 
| 
       71 
     | 
    
         
            -
            	end
         
     | 
| 
      
 17 
     | 
    
         
            +
            			opts[:limit_memory] = memory_limit
         
     | 
| 
       72 
18 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
            			@logger = (options[:logger] or Logger.new('/dev/null'))
         
     | 
| 
      
 19 
     | 
    
         
            +
            			thumbnailer.load(req.body, opts).use do |input_image|
         
     | 
| 
      
 20 
     | 
    
         
            +
            				log.info "original image loaded: #{input_image.mime_type}"
         
     | 
| 
      
 21 
     | 
    
         
            +
            				res["X-Input-Image-Content-Type"] = input_image.mime_type
         
     | 
| 
       77 
22 
     | 
    
         | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            				mw = mw.to_i
         
     | 
| 
       82 
     | 
    
         
            -
            				mh = mh.to_i
         
     | 
| 
       83 
     | 
    
         
            -
            				@logger.info "Using max size hint of: #{mw}x#{mh}"
         
     | 
| 
       84 
     | 
    
         
            -
            			end
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
            			begin
         
     | 
| 
       87 
     | 
    
         
            -
            				@image = Magick::Image.from_blob(io.read) do |info|
         
     | 
| 
       88 
     | 
    
         
            -
            					if mw and mh
         
     | 
| 
       89 
     | 
    
         
            -
            						define('jpeg', 'size', "#{mw*2}x#{mh*2}")
         
     | 
| 
       90 
     | 
    
         
            -
            						define('jbig', 'size', "#{mw*2}x#{mh*2}")
         
     | 
| 
       91 
     | 
    
         
            -
            					end
         
     | 
| 
       92 
     | 
    
         
            -
            				end.first.strip!
         
     | 
| 
       93 
     | 
    
         
            -
            				@logger.info "Loaded image: #{@image.inspect}"
         
     | 
| 
       94 
     | 
    
         
            -
            				
         
     | 
| 
       95 
     | 
    
         
            -
            				if mw and mh
         
     | 
| 
       96 
     | 
    
         
            -
            					f = find_prescale_factor(mw, mh)
         
     | 
| 
       97 
     | 
    
         
            -
            					if f > 1
         
     | 
| 
       98 
     | 
    
         
            -
            						prescale(f)
         
     | 
| 
       99 
     | 
    
         
            -
            						@logger.info "Prescaled image by factor of #{f}: #{@image.inspect}"
         
     | 
| 
       100 
     | 
    
         
            -
            					end
         
     | 
| 
      
 23 
     | 
    
         
            +
            				log.info "generating thumbnail: #{spec}"
         
     | 
| 
      
 24 
     | 
    
         
            +
            				input_image.thumbnail(spec) do |image|
         
     | 
| 
      
 25 
     | 
    
         
            +
            					write 200, image.mime_type, image.data
         
     | 
| 
       101 
26 
     | 
    
         
             
            				end
         
     | 
| 
       102 
     | 
    
         
            -
            			rescue Magick::ImageMagickError => e
         
     | 
| 
       103 
     | 
    
         
            -
            				raise ImageTooLargeError, e if e.message =~ /cache resources exhausted/
         
     | 
| 
       104 
     | 
    
         
            -
            				raise UnsupportedMediaTypeError, e
         
     | 
| 
       105 
27 
     | 
    
         
             
            			end
         
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
            			@methods = methods
         
     | 
| 
       108 
     | 
    
         
            -
            		end
         
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
            		def prescale(f)
         
     | 
| 
       111 
     | 
    
         
            -
            			@image.sample!(@image.columns / f, @image.rows / f)
         
     | 
| 
       112 
28 
     | 
    
         
             
            		end
         
     | 
| 
       113 
29 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
            		 
     | 
| 
       115 
     | 
    
         
            -
            			 
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
            					width = spec.width == :input ? @image.columns : spec.width
         
     | 
| 
       118 
     | 
    
         
            -
            					height = spec.height == :input ? @image.rows : spec.height
         
     | 
| 
      
 30 
     | 
    
         
            +
            		on put, 'thumbnails', /(.*)/ do |specs|
         
     | 
| 
      
 31 
     | 
    
         
            +
            			thumbnail_specs = ThumbnailSpecs.from_uri(specs)
         
     | 
| 
      
 32 
     | 
    
         
            +
            			log.info "thumbnailing image to multiple specs: #{thumbnail_specs.join(', ')}"
         
     | 
| 
       119 
33 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
            					 
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
            					yield Thumbnail.new(image, format, spec.options)
         
     | 
| 
       125 
     | 
    
         
            -
            				end
         
     | 
| 
       126 
     | 
    
         
            -
            			rescue Magick::ImageMagickError => e
         
     | 
| 
       127 
     | 
    
         
            -
            				raise ImageTooLargeError, e if e.message =~ /cache resources exhausted/
         
     | 
| 
       128 
     | 
    
         
            -
            				raise
         
     | 
| 
      
 34 
     | 
    
         
            +
            			opts = {}
         
     | 
| 
      
 35 
     | 
    
         
            +
            			if settings[:optimization]
         
     | 
| 
      
 36 
     | 
    
         
            +
            					opts['max-width'] = thumbnail_specs.max_width
         
     | 
| 
      
 37 
     | 
    
         
            +
            					opts['max-height'] = thumbnail_specs.max_height
         
     | 
| 
       129 
38 
     | 
    
         
             
            			end
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
            				impl.call(copy, width, height, options)
         
     | 
| 
       156 
     | 
    
         
            -
            			rescue
         
     | 
| 
       157 
     | 
    
         
            -
            				copy.destroy!
         
     | 
| 
       158 
     | 
    
         
            -
            				raise
         
     | 
| 
       159 
     | 
    
         
            -
            			end
         
     | 
| 
       160 
     | 
    
         
            -
            		end
         
     | 
| 
       161 
     | 
    
         
            -
            	end
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
            	class Thumbnail
         
     | 
| 
       164 
     | 
    
         
            -
            		def initialize(image, format, options = {})
         
     | 
| 
       165 
     | 
    
         
            -
            			@image = image
         
     | 
| 
       166 
     | 
    
         
            -
            			@format = format
         
     | 
| 
       167 
     | 
    
         
            -
            			@quality = (options['quality'] or default_quality(format))
         
     | 
| 
       168 
     | 
    
         
            -
            			@quality &&= @quality.to_i
         
     | 
| 
       169 
     | 
    
         
            -
            		end
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
            		def data
         
     | 
| 
       172 
     | 
    
         
            -
            				format = @format
         
     | 
| 
       173 
     | 
    
         
            -
            				quality = @quality
         
     | 
| 
       174 
     | 
    
         
            -
            				@image.to_blob do
         
     | 
| 
       175 
     | 
    
         
            -
            					self.format = format
         
     | 
| 
       176 
     | 
    
         
            -
            					self.quality = quality if quality
         
     | 
| 
      
 39 
     | 
    
         
            +
            			opts[:limit_memory] = memory_limit
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            			thumbnailer.load(req.body, opts).use do |input_image|
         
     | 
| 
      
 42 
     | 
    
         
            +
            				log.info "original image loaded: #{input_image.mime_type}"
         
     | 
| 
      
 43 
     | 
    
         
            +
            				write_preamble 200, "X-Input-Image-Content-Type" => input_image.mime_type
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            				thumbnail_specs.each do |spec|
         
     | 
| 
      
 46 
     | 
    
         
            +
            					log.info "generating thumbnail: #{spec}"
         
     | 
| 
      
 47 
     | 
    
         
            +
            					begin
         
     | 
| 
      
 48 
     | 
    
         
            +
            						input_image.thumbnail(spec) do |image|
         
     | 
| 
      
 49 
     | 
    
         
            +
            							write_part image.mime_type, image.data
         
     | 
| 
      
 50 
     | 
    
         
            +
            						end
         
     | 
| 
      
 51 
     | 
    
         
            +
            					rescue => error
         
     | 
| 
      
 52 
     | 
    
         
            +
            						case error
         
     | 
| 
      
 53 
     | 
    
         
            +
            						when Plugin::Thumbnailer::ImageTooLargeError
         
     | 
| 
      
 54 
     | 
    
         
            +
            							write_error_part 413, error
         
     | 
| 
      
 55 
     | 
    
         
            +
            						when Plugin::Thumbnailer::UnsupportedMethodError
         
     | 
| 
      
 56 
     | 
    
         
            +
            							write_error_part 400, error
         
     | 
| 
      
 57 
     | 
    
         
            +
            						when Plugin::Thumbnailer::ZeroSizedImageError
         
     | 
| 
      
 58 
     | 
    
         
            +
            							write_error_part 400, error
         
     | 
| 
      
 59 
     | 
    
         
            +
            						else
         
     | 
| 
      
 60 
     | 
    
         
            +
            							log.error "unhandled error while generating multipart response for thumbnail spec: #{spec}", error
         
     | 
| 
      
 61 
     | 
    
         
            +
            							write_error_part 500, error
         
     | 
| 
      
 62 
     | 
    
         
            +
            						end
         
     | 
| 
      
 63 
     | 
    
         
            +
            					end
         
     | 
| 
       177 
64 
     | 
    
         
             
            				end
         
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
            		def mime_type
         
     | 
| 
       181 
     | 
    
         
            -
            			#@image.mime_type cannot be used since it is raw loaded image
         
     | 
| 
       182 
     | 
    
         
            -
            			#TODO: how do I do it better?
         
     | 
| 
       183 
     | 
    
         
            -
            			mime = case @format
         
     | 
| 
       184 
     | 
    
         
            -
            				when 'JPG' then 'jpeg'
         
     | 
| 
       185 
     | 
    
         
            -
            				else @format.downcase
         
     | 
| 
      
 65 
     | 
    
         
            +
            				write_epilogue
         
     | 
| 
       186 
66 
     | 
    
         
             
            			end
         
     | 
| 
       187 
     | 
    
         
            -
            			"image/#{mime}"
         
     | 
| 
       188 
67 
     | 
    
         
             
            		end
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
            		private
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
            		def default_quality(format)
         
     | 
| 
       193 
     | 
    
         
            -
            			case format
         
     | 
| 
       194 
     | 
    
         
            -
            			when /png/i
         
     | 
| 
       195 
     | 
    
         
            -
            				95 # max zlib compression, adaptive filtering (photo)
         
     | 
| 
       196 
     | 
    
         
            -
            			when /jpeg|jpg/i
         
     | 
| 
       197 
     | 
    
         
            -
            				85
         
     | 
| 
       198 
     | 
    
         
            -
            			else
         
     | 
| 
       199 
     | 
    
         
            -
            				nil
         
     | 
| 
       200 
     | 
    
         
            -
            			end
         
     | 
| 
       201 
     | 
    
         
            -
            		end
         
     | 
| 
       202 
     | 
    
         
            -
            	end
         
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
            	def initialize(options = {})
         
     | 
| 
       205 
     | 
    
         
            -
            		@methods = {}
         
     | 
| 
       206 
     | 
    
         
            -
            		@options = options
         
     | 
| 
       207 
     | 
    
         
            -
            		@logger = (options[:logger] or Logger.new('/dev/null'))
         
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
            		@logger.info "Initializing thumbniler"
         
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
            		set_limit(:area, options[:limit_area]) if options.member?(:limit_area)
         
     | 
| 
       212 
     | 
    
         
            -
            		set_limit(:memory, options[:limit_memory]) if options.member?(:limit_memory)
         
     | 
| 
       213 
     | 
    
         
            -
            		set_limit(:map, options[:limit_map]) if options.member?(:limit_map)
         
     | 
| 
       214 
     | 
    
         
            -
            		set_limit(:disk, options[:limit_disk]) if options.member?(:limit_disk)
         
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
       216 
     | 
    
         
            -
            		@images = 0
         
     | 
| 
       217 
     | 
    
         
            -
            		Magick.trace_proc = lambda do |which, description, id, method|
         
     | 
| 
       218 
     | 
    
         
            -
            			case which
         
     | 
| 
       219 
     | 
    
         
            -
            			when :c
         
     | 
| 
       220 
     | 
    
         
            -
            				@images += 1
         
     | 
| 
       221 
     | 
    
         
            -
            			when :d
         
     | 
| 
       222 
     | 
    
         
            -
            				@images -= 1
         
     | 
| 
       223 
     | 
    
         
            -
            			end
         
     | 
| 
       224 
     | 
    
         
            -
            			@logger.debug "Image event: #{which}, #{description}, #{id}, #{method}: loaded images: #{images}"
         
     | 
| 
       225 
     | 
    
         
            -
            		end
         
     | 
| 
       226 
     | 
    
         
            -
            	end
         
     | 
| 
       227 
     | 
    
         
            -
             
     | 
| 
       228 
     | 
    
         
            -
            	def load(io, options = {})
         
     | 
| 
       229 
     | 
    
         
            -
            		ImageHandler.new do
         
     | 
| 
       230 
     | 
    
         
            -
            			InputImage.new(io, @methods, @options.merge(options))
         
     | 
| 
       231 
     | 
    
         
            -
            		end
         
     | 
| 
       232 
     | 
    
         
            -
            	end
         
     | 
| 
       233 
     | 
    
         
            -
             
     | 
| 
       234 
     | 
    
         
            -
            	def images
         
     | 
| 
       235 
     | 
    
         
            -
            		@images
         
     | 
| 
       236 
     | 
    
         
            -
            	end
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
            	def method(method, &impl)
         
     | 
| 
       239 
     | 
    
         
            -
            		@methods[method] = impl
         
     | 
| 
       240 
     | 
    
         
            -
            	end
         
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
       242 
     | 
    
         
            -
            	def set_limit(limit, value)
         
     | 
| 
       243 
     | 
    
         
            -
            		old = Magick.limit_resource(limit, value)
         
     | 
| 
       244 
     | 
    
         
            -
            		@logger.info "Changed limit of #{limit} from #{old} to #{value}"
         
     | 
| 
       245 
68 
     | 
    
         
             
            	end
         
     | 
| 
       246 
69 
     | 
    
         
             
            end
         
     | 
| 
       247 
70 
     | 
    
         | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
         
     | 
| 
      
 2 
     | 
    
         
            +
            tiny,103,82,80,96,71,103,0.0,0.717800047388741,15.11025177882002
         
     | 
| 
      
 3 
     | 
    
         
            +
            small,103,65,66,76,55,87,0.0,0.717760031219077,21.124855293828656
         
     | 
| 
      
 4 
     | 
    
         
            +
            medium,102,75,73,86,67,105,0.0,0.7177993117571305,22.47959582884709
         
     | 
| 
      
 5 
     | 
    
         
            +
            large,102,89,87,102,79,123,0.0,0.717713449387129,36.01533749683362
         
     | 
| 
      
 6 
     | 
    
         
            +
            extra large,102,346,344,366,327,381,0.0,0.7165034631000717,15.041674752209218
         
     | 
| 
      
 7 
     | 
    
         
            +
            extra large w prescale,102,328,324,349,306,455,0.0,0.716594070535338,17.247243615638613
         
     | 
| 
      
 8 
     | 
    
         
            +
            large PNG,102,241,237,257,227,314,0.0,0.7170877799805965,31.675812062365548
         
     | 
| 
      
 9 
     | 
    
         
            +
            large PNG w prescale,102,165,162,182,152,214,0.0,0.7173802959545378,36.088292173345806
         
     | 
| 
      
 10 
     | 
    
         
            +
            TOTAL,818,174,119,341,55,455,0.0,5.697092950369823,193.23852724401388
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
         
     | 
| 
      
 2 
     | 
    
         
            +
            tiny,70,40,37,40,34,235,0.0,0.6569130716316782,50.04022492820879
         
     | 
| 
      
 3 
     | 
    
         
            +
            small,70,46,47,50,43,53,0.0,0.6580864725624946,54.222726428752736
         
     | 
| 
      
 4 
     | 
    
         
            +
            medium,70,64,65,68,60,72,0.0,0.6579689438658495,57.46240691501861
         
     | 
| 
      
 5 
     | 
    
         
            +
            large,70,108,107,115,96,121,0.0,0.6577834576857298,68.1197722366047
         
     | 
| 
      
 6 
     | 
    
         
            +
            extra large,70,390,394,405,66,423,0.014285714285714285,0.65809265944645,35.05713213795502
         
     | 
| 
      
 7 
     | 
    
         
            +
            extra large w prescale,69,364,364,370,353,389,0.0,0.6564176719053236,37.55362936838826
         
     | 
| 
      
 8 
     | 
    
         
            +
            large PNG,69,304,304,316,273,332,0.0,0.6568863586599518,64.13366268885483
         
     | 
| 
      
 9 
     | 
    
         
            +
            large PNG w prescale,69,195,196,202,187,204,0.0,0.6574183467357749,68.18789317070963
         
     | 
| 
      
 10 
     | 
    
         
            +
            TOTAL,557,188,118,387,34,423,0.0017953321364452424,5.212768944250512,430.79905008223915
         
     | 
    
        data/load_test/load_test.jmx
    CHANGED
    
    | 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            <?xml version="1.0" encoding="UTF-8"?>
         
     | 
| 
       2 
     | 
    
         
            -
            <jmeterTestPlan version="1.2" properties="2. 
     | 
| 
      
 2 
     | 
    
         
            +
            <jmeterTestPlan version="1.2" properties="2.4" jmeter="2.9 r1437961">
         
     | 
| 
       3 
3 
     | 
    
         
             
              <hashTree>
         
     | 
| 
       4 
4 
     | 
    
         
             
                <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Plan testów" enabled="true">
         
     | 
| 
       5 
5 
     | 
    
         
             
                  <stringProp name="TestPlan.comments"></stringProp>
         
     | 
| 
         @@ -9,7 +9,7 @@ 
     | 
|
| 
       9 
9 
     | 
    
         
             
                    <collectionProp name="Arguments.arguments">
         
     | 
| 
       10 
10 
     | 
    
         
             
                      <elementProp name="media" elementType="Argument">
         
     | 
| 
       11 
11 
     | 
    
         
             
                        <stringProp name="Argument.name">media</stringProp>
         
     | 
| 
       12 
     | 
    
         
            -
                        <stringProp name="Argument.value">/ 
     | 
| 
      
 12 
     | 
    
         
            +
                        <stringProp name="Argument.value">/home/kazuya/Documents/httpthumbnailer/load_test</stringProp>
         
     | 
| 
       13 
13 
     | 
    
         
             
                        <stringProp name="Argument.metadata">=</stringProp>
         
     | 
| 
       14 
14 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       15 
15 
     | 
    
         
             
                    </collectionProp>
         
     | 
| 
         @@ -17,6 +17,21 @@ 
     | 
|
| 
       17 
17 
     | 
    
         
             
                  <stringProp name="TestPlan.user_define_classpath"></stringProp>
         
     | 
| 
       18 
18 
     | 
    
         
             
                </TestPlan>
         
     | 
| 
       19 
19 
     | 
    
         
             
                <hashTree>
         
     | 
| 
      
 20 
     | 
    
         
            +
                  <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
         
     | 
| 
      
 21 
     | 
    
         
            +
                    <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
         
     | 
| 
      
 22 
     | 
    
         
            +
                      <collectionProp name="Arguments.arguments"/>
         
     | 
| 
      
 23 
     | 
    
         
            +
                    </elementProp>
         
     | 
| 
      
 24 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.domain">localhost</stringProp>
         
     | 
| 
      
 25 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.port">3100</stringProp>
         
     | 
| 
      
 26 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.connect_timeout"></stringProp>
         
     | 
| 
      
 27 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.response_timeout"></stringProp>
         
     | 
| 
      
 28 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
      
 29 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
      
 30 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.path"></stringProp>
         
     | 
| 
      
 31 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.implementation">Java</stringProp>
         
     | 
| 
      
 32 
     | 
    
         
            +
                    <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
         
     | 
| 
      
 33 
     | 
    
         
            +
                  </ConfigTestElement>
         
     | 
| 
      
 34 
     | 
    
         
            +
                  <hashTree/>
         
     | 
| 
       20 
35 
     | 
    
         
             
                  <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Grupa wątków" enabled="true">
         
     | 
| 
       21 
36 
     | 
    
         
             
                    <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
         
     | 
| 
       22 
37 
     | 
    
         
             
                    <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
         
     | 
| 
         @@ -36,13 +51,13 @@ 
     | 
|
| 
       36 
51 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       37 
52 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       38 
53 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       39 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       40 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 54 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 55 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       41 
56 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       42 
57 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       43 
58 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       44 
59 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       45 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 60 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,128,128,PNG/pad,200,200,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       46 
61 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       47 
62 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       48 
63 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -72,7 +87,7 @@ 
     | 
|
| 
       72 
87 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       73 
88 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       74 
89 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       75 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 90 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">20000</stringProp>
         
     | 
| 
       76 
91 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       77 
92 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       78 
93 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -113,13 +128,13 @@ 
     | 
|
| 
       113 
128 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       114 
129 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       115 
130 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       116 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       117 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 131 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 132 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       118 
133 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       119 
134 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       120 
135 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       121 
136 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       122 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 137 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,128,128,PNG/pad,200,200,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       123 
138 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       124 
139 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       125 
140 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -149,7 +164,7 @@ 
     | 
|
| 
       149 
164 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       150 
165 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       151 
166 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       152 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 167 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">20000</stringProp>
         
     | 
| 
       153 
168 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       154 
169 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       155 
170 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -190,13 +205,13 @@ 
     | 
|
| 
       190 
205 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       191 
206 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       192 
207 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       193 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       194 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 208 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 209 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       195 
210 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       196 
211 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       197 
212 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       198 
213 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       199 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 214 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,128,128,PNG/pad,200,200,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       200 
215 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       201 
216 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       202 
217 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -226,7 +241,7 @@ 
     | 
|
| 
       226 
241 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       227 
242 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       228 
243 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       229 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 244 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">20000</stringProp>
         
     | 
| 
       230 
245 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       231 
246 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       232 
247 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -267,13 +282,13 @@ 
     | 
|
| 
       267 
282 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       268 
283 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       269 
284 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       270 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       271 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 285 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 286 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       272 
287 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       273 
288 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       274 
289 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       275 
290 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       276 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 291 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,128,128,PNG/pad,200,200,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       277 
292 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       278 
293 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       279 
294 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -303,7 +318,7 @@ 
     | 
|
| 
       303 
318 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       304 
319 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       305 
320 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       306 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 321 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">20000</stringProp>
         
     | 
| 
       307 
322 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       308 
323 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       309 
324 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -344,13 +359,13 @@ 
     | 
|
| 
       344 
359 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       345 
360 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       346 
361 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       347 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       348 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 362 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 363 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       349 
364 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       350 
365 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       351 
366 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       352 
367 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       353 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 368 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,200,50,PNG/pad,64,64,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       354 
369 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       355 
370 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       356 
371 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -380,7 +395,7 @@ 
     | 
|
| 
       380 
395 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       381 
396 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       382 
397 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       383 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 398 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">20000</stringProp>
         
     | 
| 
       384 
399 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       385 
400 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       386 
401 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -421,13 +436,13 @@ 
     | 
|
| 
       421 
436 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       422 
437 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       423 
438 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       424 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       425 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 439 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 440 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       426 
441 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       427 
442 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       428 
443 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       429 
444 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       430 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 445 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,100,100,PNG/pad,64,64,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       431 
446 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       432 
447 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       433 
448 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -457,7 +472,7 @@ 
     | 
|
| 
       457 
472 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       458 
473 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       459 
474 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       460 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 475 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">4000</stringProp>
         
     | 
| 
       461 
476 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       462 
477 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       463 
478 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -498,13 +513,13 @@ 
     | 
|
| 
       498 
513 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       499 
514 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       500 
515 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       501 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       502 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 516 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 517 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       503 
518 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       504 
519 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       505 
520 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       506 
521 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       507 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 522 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,128,128,PNG/pad,129,310,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       508 
523 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       509 
524 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       510 
525 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -534,7 +549,7 @@ 
     | 
|
| 
       534 
549 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       535 
550 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       536 
551 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       537 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 552 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">20000</stringProp>
         
     | 
| 
       538 
553 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       539 
554 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       540 
555 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -575,13 +590,13 @@ 
     | 
|
| 
       575 
590 
     | 
    
         
             
                      <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Zmienne zdefiniowane przez użytkownika" enabled="true">
         
     | 
| 
       576 
591 
     | 
    
         
             
                        <collectionProp name="Arguments.arguments"/>
         
     | 
| 
       577 
592 
     | 
    
         
             
                      </elementProp>
         
     | 
| 
       578 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.domain" 
     | 
| 
       579 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.port" 
     | 
| 
      
 593 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.domain"></stringProp>
         
     | 
| 
      
 594 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.port"></stringProp>
         
     | 
| 
       580 
595 
     | 
    
         
             
                      <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
         
     | 
| 
       581 
596 
     | 
    
         
             
                      <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
         
     | 
| 
       582 
597 
     | 
    
         
             
                      <stringProp name="HTTPSampler.protocol"></stringProp>
         
     | 
| 
       583 
598 
     | 
    
         
             
                      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
         
     | 
| 
       584 
     | 
    
         
            -
                      <stringProp name="HTTPSampler.path">/ 
     | 
| 
      
 599 
     | 
    
         
            +
                      <stringProp name="HTTPSampler.path">/thumbnails/crop,128,128,PNG/pad,200,200,JPEG/fit,60,60,JPEG</stringProp>
         
     | 
| 
       585 
600 
     | 
    
         
             
                      <stringProp name="HTTPSampler.method">PUT</stringProp>
         
     | 
| 
       586 
601 
     | 
    
         
             
                      <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
         
     | 
| 
       587 
602 
     | 
    
         
             
                      <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
         
     | 
| 
         @@ -611,7 +626,7 @@ 
     | 
|
| 
       611 
626 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
       612 
627 
     | 
    
         
             
                      <SizeAssertion guiclass="SizeAssertionGui" testclass="SizeAssertion" testname="Size Assertion" enabled="true">
         
     | 
| 
       613 
628 
     | 
    
         
             
                        <stringProp name="Assertion.test_field">SizeAssertion.response_network_size</stringProp>
         
     | 
| 
       614 
     | 
    
         
            -
                        <stringProp name="SizeAssertion.size"> 
     | 
| 
      
 629 
     | 
    
         
            +
                        <stringProp name="SizeAssertion.size">2000</stringProp>
         
     | 
| 
       615 
630 
     | 
    
         
             
                        <intProp name="SizeAssertion.operator">5</intProp>
         
     | 
| 
       616 
631 
     | 
    
         
             
                      </SizeAssertion>
         
     | 
| 
       617 
632 
     | 
    
         
             
                      <hashTree/>
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
         
     | 
| 
      
 2 
     | 
    
         
            +
            crop 100x100 JPEG,9434,163,82,218,15,24355,1.0599957600169599E-4,1.7563116635924076,7.3452512218341335
         
     | 
| 
      
 3 
     | 
    
         
            +
            crop 800x600 JPEG,9434,488,401,962,16,5910,1.0599957600169599E-4,1.7563185299796351,149.11867662526254
         
     | 
| 
      
 4 
     | 
    
         
            +
            crop 300x400 PNG,9434,478,443,737,14,1597,1.0599957600169599E-4,1.7561867701093066,199.61794605857165
         
     | 
| 
      
 5 
     | 
    
         
            +
            pad 100x100 JPEG,9434,71,54,126,9,2378,1.0599957600169599E-4,1.7562374446428708,5.336457821295207
         
     | 
| 
      
 6 
     | 
    
         
            +
            fit 100x100 JPEG,9434,69,53,123,6,1162,1.0599957600169599E-4,1.7562184822169382,5.510921170998325
         
     | 
| 
      
 7 
     | 
    
         
            +
            limit 100x100 JPEG,9434,68,53,119,7,1239,1.0599957600169599E-4,1.7561969047820718,5.509383664985987
         
     | 
| 
      
 8 
     | 
    
         
            +
            limit 500x500 JPEG,9434,382,323,701,7,1612,1.0599957600169599E-4,1.7560298610700056,69.28159162507869
         
     | 
| 
      
 9 
     | 
    
         
            +
            limit 1500x1500 JPEG,9434,625,190,1582,7,10883,1.0599957600169599E-4,1.7556814925042041,315.8534505970671
         
     | 
| 
      
 10 
     | 
    
         
            +
            multipart,9434,2746,1331,5595,7,59639,1.0599957600169599E-4,1.752705741811247,755.3157395719443
         
     | 
| 
      
 11 
     | 
    
         
            +
            TOTAL,84906,566,160,1114,6,59639,1.0599957600169599E-4,15.770876685474601,1511.1397532008416
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
         
     | 
| 
      
 2 
     | 
    
         
            +
            crop 100x100 JPEG,21302,83,76,121,7,526,0.0,5.616822094767196,20.108323048878113
         
     | 
| 
      
 3 
     | 
    
         
            +
            crop 800x600 JPEG,21302,189,155,257,29,1453,0.0,5.616656225412957,281.666478061634
         
     | 
| 
      
 4 
     | 
    
         
            +
            crop 300x400 PNG,21300,779,724,1303,83,2521,9.389671361502347E-5,5.616171832709798,670.9580779119093
         
     | 
| 
      
 5 
     | 
    
         
            +
            pad 100x100 JPEG,21297,77,72,116,7,399,0.0,5.616655915277294,16.87093942473386
         
     | 
| 
      
 6 
     | 
    
         
            +
            fit 100x100 JPEG,21296,63,57,98,6,332,0.0,5.616451434415746,17.080941226295707
         
     | 
| 
      
 7 
     | 
    
         
            +
            limit 100x100 JPEG,21295,63,57,99,6,382,0.0,5.61638026072453,17.053713965378755
         
     | 
| 
      
 8 
     | 
    
         
            +
            limit 500x500 JPEG,21295,77,24,193,6,1101,0.0,5.6162750922485385,98.95595626808739
         
     | 
| 
      
 9 
     | 
    
         
            +
            limit 1500x1500 JPEG,21294,78,24,97,5,1606,0.0,5.616492770090949,201.99272878375396
         
     | 
| 
      
 10 
     | 
    
         
            +
            TOTAL,170381,176,73,531,5,2521,1.1738398060816641E-5,44.920480038344856,1324.468317085056
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
         
     | 
| 
      
 2 
     | 
    
         
            +
            crop 100x100 JPEG,9435,269,179,369,25,18054,1.0598834128245893E-4,1.4530576892393956,6.075741393665208
         
     | 
| 
      
 3 
     | 
    
         
            +
            crop 800x600 JPEG,9435,510,411,1049,16,5303,1.0598834128245893E-4,1.452948715915186,123.36523433499724
         
     | 
| 
      
 4 
     | 
    
         
            +
            crop 300x400 PNG,9435,796,756,1223,18,3270,1.0598834128245893E-4,1.4527849510264421,164.89592090446297
         
     | 
| 
      
 5 
     | 
    
         
            +
            pad 100x100 JPEG,9435,192,166,308,18,2416,1.0598834128245893E-4,1.4527661606954925,4.414348853769809
         
     | 
| 
      
 6 
     | 
    
         
            +
            fit 100x100 JPEG,9435,170,143,295,12,2856,1.0598834128245893E-4,1.4527753321058268,4.558875497086674
         
     | 
| 
      
 7 
     | 
    
         
            +
            limit 100x100 JPEG,9435,170,142,292,6,1823,1.0598834128245893E-4,1.4527587789127483,4.557606634765511
         
     | 
| 
      
 8 
     | 
    
         
            +
            limit 500x500 JPEG,9435,439,344,857,6,4214,1.0598834128245893E-4,1.45265879669967,57.31115234766828
         
     | 
| 
      
 9 
     | 
    
         
            +
            limit 1500x1500 JPEG,9435,562,203,1453,5,9851,1.0598834128245893E-4,1.4525192472270894,261.3371834603011
         
     | 
| 
      
 10 
     | 
    
         
            +
            multipart,9435,3061,2065,5523,6,39289,1.0598834128245893E-4,1.452267946899481,625.640618812998
         
     | 
| 
      
 11 
     | 
    
         
            +
            TOTAL,84915,685,250,1498,5,39289,1.0598834128245893E-4,13.067971611961191,1251.7379056145878
         
     |