module Apache::ImageResizer::Util

Constants

DEFAULT_FORMAT
DEFAULT_HEIGHT
DEFAULT_MAX_DIM
DEFAULT_PREFIX_RE
DEFAULT_PROXY_CACHE
DEFAULT_SOURCE_DIR
DEFAULT_VERBOSITY
DIRECTIVES_RE
MIME_RE
PROXY_RE
REPLACE

Public Instance Methods

extract_directives(path) click to toggle source
    # File lib/apache/image_resizer/util.rb
151 def extract_directives(path)
152   return unless path.sub!(DIRECTIVES_RE, '')
153   match, directives, max = Regexp.last_match, {}, @max_dim
154 
155   if o = match[3]
156     wh = [o.to_f, match[4].to_f]
157     xy = match.values_at(5, 6)
158 
159     if wh.all? { |i| 0 < i && i <= max }
160       directives[:offset] = xy.map! { |i| i.tr!('pm', '+-').to_f }.concat(wh)
161     else
162       return
163     end
164   end
165 
166   if w = match[1]
167     h = match[2]
168 
169     wh = [w.to_f]
170     wh << h.to_f if h
171 
172     max *= 2 if o
173 
174     if wh.all? { |i| 0 < i && i <= max }
175       directives[:resize] = wh
176     else
177       return
178     end
179   end
180 
181   [directives, match[0]]
182 end
get_paths(request, path, base, prefix, source_dir, target_dir, proxy_cache, secret) click to toggle source
    # File lib/apache/image_resizer/util.rb
184 def get_paths(request, path, base, prefix, source_dir, target_dir, proxy_cache, secret)
185   real_base = request.lookup_uri(base).filename.untaint
186   target    = File.join(real_base, prefix, target_dir, path).untaint
187   return [nil, target] if File.exist?(target)
188 
189   source = request.lookup_uri(url_for(File.join(base, prefix,
190     source_dir, path.sub(*REPLACE.reverse)), secret)).filename.untaint
191   return [source, target] unless source.sub!(PROXY_RE, '') && proxy_cache
192 
193   cache = File.join(real_base, prefix, proxy_cache, path).untaint
194   return [cache, target] if File.exist?(cache)
195 
196   begin
197     URI.get_redirect(source) { |res|
198       if res.is_a?(Net::HTTPSuccess) && res.content_type =~ MIME_RE
199         content = res.body.untaint
200 
201         mkdir_for(cache)
202         File.open(cache, 'w') { |f| f.write(content) }
203 
204         return [cache, target]
205       end
206     }
207   rescue => err
208     log_err(err, "#{source} => #{cache}")
209   end
210 
211   [source, target]
212 end
parse_url(url, base, prefix_re, &block) click to toggle source
    # File lib/apache/image_resizer/util.rb
133 def parse_url(url, base, prefix_re, &block)
134   block ||= lambda { |*| }
135 
136   return block['No URL'] unless url
137 
138   path = Apache::SecureDownload::Util.real_path(url)
139   return block['Invalid Format'] unless path.sub!(
140     %r{\A#{Regexp.escape(base)}/(#{prefix_re})}, ''
141   )
142 
143   prefix, directives, dir = $1 || '', *extract_directives(path)
144   return block['Invalid Directives'] unless directives
145   return block['No Path'] if path.empty?
146   return block['No File'] if path =~ %r{/\z}
147 
148   [path, prefix, directives, dir]
149 end
resize(source, target, directives, enlarge, &block) click to toggle source
    # File lib/apache/image_resizer/util.rb
214 def resize(source, target, directives, enlarge, &block)
215   img = do_magick('Read', source, block) { |value|
216     Magick::Image.read(value).first
217   } or return
218 
219   resize, offset = directives.values_at(:resize, :offset)
220   link = !offset
221 
222   if resize
223     c, r = img.columns, img.rows
224 
225     w, h = resize
226     h  ||= DEFAULT_HEIGHT
227 
228     unless enlarge || offset
229       w = [w, c].min
230       h = [h, r].min
231     end
232 
233     img.resize_to_fit!(w, h)
234 
235     link &&= img.columns == c && img.rows == r
236   end
237 
238   if offset
239     img.crop!(*offset)
240   end
241 
242   mkdir_for(target)
243 
244   if link
245     source = File.expand_path(File.readlink(source),
246       File.dirname(source)) if File.symlink?(source)
247 
248     if system('ln', source.untaint, target)
249       return img
250     elsif block
251       block['Link error: %s' % $?.exitstatus]
252     end
253   end
254 
255   do_magick('Write', target, block) { |value|
256     img.write(value) or raise Magick::ImageMagickError
257   }
258 rescue => err
259   log_err(err)
260   block['Resize Error: %s' % err] if block
261 end
resize_url(size = DEFAULT_SOURCE_DIR, *path) click to toggle source
    # File lib/apache/image_resizer/util.rb
111 def resize_url(size = DEFAULT_SOURCE_DIR, *path)
112   case size
113     when String  then nil
114     when Numeric then size = "r#{size}"
115     when Array   then size = "r#{size.join('x')}"
116     when Hash    then size = size.map { |k, v| case k.to_s
117       when /\A[rs]/
118         "r#{Array(v).join('x')}" if v
119       when /\Ao/
120         x, y, w, h = v
121         "o#{w}x#{h}#{x < 0 ? 'm' : 'p'}#{x.abs}#{y < 0 ? 'm' : 'p'}#{y.abs}"
122     end }.compact.join
123   end
124 
125   if path.empty?
126     size
127   else
128     file = path.pop.sub(*REPLACE)
129     File.join(path << size << file)
130   end
131 end
secure_resize_url(secret, args = [], options = {}) click to toggle source
    # File lib/apache/image_resizer/util.rb
107 def secure_resize_url(secret, args = [], options = {})
108   url_for(resize_url(*args), secret, options)
109 end
send_image(request, target, img = nil) { |'Send Error'| ... } click to toggle source
    # File lib/apache/image_resizer/util.rb
263 def send_image(request, target, img = nil)
264   File.open(target) { |f|
265     request.content_type = (t = img && img.format) ?
266       "image/#{t.downcase}" : f.content_type
267 
268     request.status = HTTP_OK
269     request.send_fd(f)
270   }
271 rescue IOError => err
272   request.log_reason(err.message, target)
273   yield('Send Error') if block_given?
274 end

Private Instance Methods

do_magick(what, value, block) { |value| ... } click to toggle source
    # File lib/apache/image_resizer/util.rb
278 def do_magick(what, value, block)
279   yield value
280 rescue Magick::ImageMagickError => err
281   unless value.start_with?(DEFAULT_FORMAT)
282     value = "#{DEFAULT_FORMAT}#{value}"
283     retry
284   else
285     block['%s Error: %s' % [what, err]] if block
286   end
287 end
log(level = 1, loc = 0, trace = nil) { || ... } click to toggle source
    # File lib/apache/image_resizer/util.rb
304 def log(level = 1, loc = 0, trace = nil)
305   return if @verbosity < level
306 
307   case msg = yield
308     when Array then msg = msg.shift % msg
309     when Hash  then msg = msg.map { |k, v|
310       "#{k} = #{v.inspect}"
311     }.join(', ')
312   end
313 
314   warn "#{caller[loc]}: #{msg}#{" [#{trace.join(', ')}]" if trace}"
315 end
log_err(err, msg = nil) click to toggle source
    # File lib/apache/image_resizer/util.rb
298 def log_err(err, msg = nil)
299   log(0, 1, err.backtrace) {
300     "[ERROR] #{"#{msg}: " if msg}#{err} (#{err.class})"
301   }
302 end
mkdir_for(path) click to toggle source
    # File lib/apache/image_resizer/util.rb
289 def mkdir_for(path)
290   dir = File.dirname(path).untaint
291   FileUtils.mkdir_p(dir) unless File.exist?(dir)
292 end
url_for(url, sec = nil, opt = {}) click to toggle source
    # File lib/apache/image_resizer/util.rb
294 def url_for(url, sec = nil, opt = {})
295   sec ? Apache::SecureDownload::Util.secure_url(sec, url, opt) : url
296 end