Intervention / imagecache

Caching extension for the Intervention Image Class
https://image.intervention.io/v2/usage/cache
MIT License
638 stars 118 forks source link

Sanity check... #6

Closed pobtastic closed 10 years ago

pobtastic commented 11 years ago

So sorry to feel the need to ask. I'm just struggling a bit with whether what I've done is a good way to implement image caching or not - and there doesn't seem to be a whole heap of examples around for how to utilise imagecache. Thank you for your excellent work BTW!

/*
|--------------------------------------------------------------------------
| Imagecache Routes
|--------------------------------------------------------------------------
*/
Route::any('imagecache/{style}/{filepath}', array('as' => 'imagecache', function($style, $filepath)
{
  // Get the full path to the image (locked to the 'public/assets' folder).
  $filepath = public_path() . "/assets/{$filepath}";

  // 404 if the image doesn't exist.
  if (!File::isFile($filepath))
  {
    App::abort(404, 'File not found');
  }

  // Produce the cached image.
  $image = Image::cache(function($image) use ($style, $filepath)
  {
    // Switch on the passed image style preset.
    switch ($style)
    {
      case 'square_thumbnail':
        return $image->make($filepath)->resize(100, 100, false)->greyscale();
      case 'thumbnail':
        return $image->make($filepath)->resize(100, 100, true)->greyscale();
      case 'medium':
        return $image->make($filepath)->resize(220, 220, true);
      case 'large':
        return $image->make($filepath)->resize(480, 480, true);
      case 'preview':
        return $image->make($filepath)->resize(640, null, true);
      // 404 if there's no such image style preset.
      default:
        App::abort(404, 'Image style not found');
    }

  }, 10, true);

  // Return an image response.
  return Response::make($image, 200, array('content-type' => 'image/jpg'));
}))->where('filepath', '.*');

My concerns are;

Any advice or comments would be very much appreciated, thank you.

olivervogel commented 11 years ago

Like the article points out, I think on-demand image generation is not the best way to go.

I think for high traffic websites I would move the image resizing workload to the background (with or without cache), so the user doesn't notice any delay and the risk of being DDOS'ed is eliminated.

Also may also consider using Varnish if you're dealing with high traffic.

pobtastic commented 11 years ago

Thank you for your response.

The Drupal DDOS issue is different to the one I'm facing. Drupal suffers from a multitude of sickness in the image caching area, whereas Laravel does not - for Drupal all the files reside under a common public (or private) 'files' directory - therefore Drupals imagecache has the run of all of the files at this location (as the article mentions, even PDFs can be processed by imagemagick) which in turn means that the cached files themselves can then become targets.

Fortunately with Laravel the cache files are served via the storage directory, so this isn't an issue (plus I've locked the available assets down further by only allowing access to "/public/assets" and not simply "public").

I think that I just wanted to take maximum advantage of the lifetime parameter provided which obviously isn't so handy when you're creating the cached presets only once!

Are there any good examples of how best to utilise the cache lifetime? Without making it route-based I can't see how best to use it?

pobtastic commented 11 years ago

Just to check... If the lifetime parameter is omitted, does this mean the image will be cached indefinitely?

ghost commented 11 years ago

I also am having issues with an empty mimetype

olivervogel commented 11 years ago

@pobtastic @brad-pb  If you return HTTP responses you should always make sure to return a proper content-type. This is part of the HTTP response and not the image processing class.

I think it would be nice, if the content-type would be set automatically. But I see no other option than to extend the Response class itself to do this. If you have any suggestions, let me know.

olivervogel commented 11 years ago

@pobtastic At the moment the default lifetime is 5 minutes.

pobtastic commented 10 years ago

Hiya, sorry I haven't replied sooner - deadlines... Isn't this how to return a correct response in Laravel?

return Response::make($image, 200, array('content-type' => 'image/jpg'));
olivervogel commented 10 years ago

I guess it's image/jpeg.