function _s3fs_image_style_deliver in S3 File System 7.3
Same name and namespace in other branches
- 7 s3fs.module \_s3fs_image_style_deliver()
- 7.2 s3fs.module \_s3fs_image_style_deliver()
Generates an image derivative in S3.
This is a re-write of the core Image module's image_style_deliver() function. It exists to improve the performance of serving newly-created image derivatives from S3.
Note to future maintainers: this function is variatic. It accepts two fixed arguments: $style and $scheme, and any number of further arguments, which represent the path to the file in S3 (split on the slashes).
1 string reference to '_s3fs_image_style_deliver'
- s3fs_menu in ./
s3fs.module - Implements hook_menu().
File
- ./
s3fs.module, line 213 - Hook implementations and other primary functionality for S3 File System.
Code
function _s3fs_image_style_deliver() {
// Drupal's black magic calls this function with the image style as arg0,
// the scheme as arg1, and the full path to the filename split across arg2+.
// So we need to use PHP's version of variatic functions to get the complete
// filename.
$args = func_get_args();
$style = array_shift($args);
$scheme = array_shift($args);
$filename = implode('/', $args);
$valid = !empty($style) && file_stream_wrapper_valid_scheme($scheme);
if (!variable_get('image_allow_insecure_derivatives', FALSE) || strpos(ltrim($filename, '\\/'), 'styles/') === 0) {
$valid = $valid && isset($_GET[IMAGE_DERIVATIVE_TOKEN]) && $_GET[IMAGE_DERIVATIVE_TOKEN] === image_style_path_token($style['name'], "{$scheme}://{$filename}");
}
if (!$valid) {
return MENU_ACCESS_DENIED;
}
$image_uri = "{$scheme}://{$filename}";
$derivative_uri = image_style_path($style['name'], $image_uri);
// Confirm that the original source image exists before trying to process it.
if (!is_file($image_uri)) {
watchdog('s3fs', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array(
'%source_image_path' => $image_uri,
'%derivative_path' => $derivative_uri,
));
return MENU_NOT_FOUND;
}
// Don't start generating the image if the derivative already exists or if
// generation is in progress in another thread.
$lock_name = "_s3fs_image_style_deliver:{$style['name']}:" . drupal_hash_base64($image_uri);
if (!file_exists($derivative_uri)) {
$lock_acquired = lock_acquire($lock_name);
if (!$lock_acquired) {
// Tell client to retry again in 3 seconds. Currently no browsers are known
// to support Retry-After.
drupal_add_http_header('Status', '503 Service Unavailable');
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
drupal_add_http_header('Retry-After', 3);
print t('Image generation in progress. Try again shortly.');
drupal_exit();
}
}
// Try to generate the image, unless another thread just did it while we were
// acquiring the lock.
$success = file_exists($derivative_uri);
if (!$success) {
// If we successfully generate the derivative, wait until S3 acknowledges
// its existence. Otherwise, redirecting to it may cause a 403 error.
$success = image_style_create_derivative($style, $image_uri, $derivative_uri);
file_stream_wrapper_get_instance_by_scheme('s3')
->waitUntilFileExists($derivative_uri);
}
if (!empty($lock_acquired)) {
lock_release($lock_name);
}
if ($success) {
if (_s3fs_get_setting('no_redirect_derivatives', False)) {
// If the site admin doesn't want us to redirect to the new derivative, we upload it to the client, instead.
$image = image_load($derivative_uri);
$settings = array(
'Content-Type' => $image->info['mime_type'],
'Content-Length' => $image->info['file_size'],
);
file_transfer($image->source, $settings);
}
else {
// Perform a 302 Redirect to the new image derivative in S3.
drupal_goto(file_create_url($derivative_uri));
}
}
else {
watchdog('S3 File System', 'Unable to generate an image derivative at %path.', array(
'%path' => $derivative_uri,
));
drupal_add_http_header('Status', '500 Internal Server Error');
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
print t('Error generating image.');
drupal_exit();
}
}