function s3fs_cors_sign_request in S3 File System CORS Upload 7
AJAX callback to create paramaters necessary for submitting a CORS request.
Use the filename, filesize, and filemime properies in $_POST in conjunction with the AWS key/secret in order to create the required parameters for sending a file to S3 via a CORS request.
The heavy lifting here is handled by the AWSSDK.
See also
s3fs_cors.js
1 string reference to 's3fs_cors_sign_request'
- s3fs_cors_menu in ./
s3fs_cors.module - Implements hook_menu().
File
- ./
s3fs_cors.module, line 525 - Allow uploading of files directly to AmazonS3 via the browser using CORS.
Code
function s3fs_cors_sign_request() {
// Be careful with these, as they are user input.
$filename = $_POST['filename'];
if (module_exists('transliteration') && variable_get('transliteration_file_uploads', 1)) {
$filename = transliteration_clean_filename($filename);
}
$filemime = $_POST['filemime'];
$form_build_id = $_POST['form_build_id'];
$field_name = $_POST['field_name'];
$library = _s3fs_load_awssdk2_library();
if (!$library['loaded']) {
$error = t('Unable to load the AWS SDK for PHP. Please check you have the library installed correctly and have your S3 credentials configured.');
header('HTTP/1.1 500 Internal Server Error');
drupal_add_http_header('Content-Type', 'application/json; charset=utf-8');
print json_encode(array(
'error' => $error,
));
drupal_exit();
}
// Retrieve the form from which this request is being made, so we can get some much-needed context.
$form_state = form_state_defaults();
$form = form_get_cache($form_build_id, $form_state);
if (!$form) {
// If $form cannot be loaded from the cache, the form_build_id in $_POST
// must be invalid, which means that someone performed a POST request onto
// system/ajax without actually viewing the concerned form in the browser.
// This is likely a hacking attempt as it never happens under normal
// circumstances, so we just do nothing.
watchdog('ajax', 'Invalid form POST data.', array(), WATCHDOG_WARNING);
drupal_exit();
}
// Get the "File directory" setting for this field, as a URI.
$instance_info = field_info_instance($form['#entity_type'], $field_name, $form['#bundle']);
$field_info = field_info_field($field_name);
// "File directory" supports tokens, so we have to do the replacement ourselves.
$file_directory = token_replace($instance_info['settings']['file_directory']);
$file_scheme = $field_info['settings']['uri_scheme'];
// S3 config and client initialization.
$config = _s3fs_get_config();
$key = $file_scheme . '_folder';
$config['root_folder'] = isset($config[$key]) ? $config[$key] : '';
$client = _s3fs_get_amazons3_client($config);
// Use file_create_filename() to avoid overwriting an existing file.
$file_directory_uri = "{$file_scheme}://{$file_directory}";
$uri = file_create_filename($filename, $file_directory_uri);
$acl = strpos($uri, 'private://') === FALSE ? 'public-read' : 'private';
$s3_scheme_prefix = !empty($config['root_folder']) ? $config['root_folder'] . '/' : '';
$s3_key = $s3_scheme_prefix . file_uri_target($uri);
$formInputs = array(
'acl' => $acl,
'Content-Type' => $filemime,
// The root folder is not part of a file's URI, so we don't add it until
// we're setting up the final s3 parameters.
'key' => $s3_key,
'X-Amz-Expires' => '21600',
'success_action_status' => '201',
);
$options = [
[
'bucket' => $config['bucket'],
],
[
'acl' => $acl,
],
[
'starts-with',
'$key',
$s3_key,
],
[
'starts-with',
'$Content-Type',
'',
],
[
'success_action_status' => '201',
],
[
'X-Amz-Expires' => '21600',
],
];
// Allow other modules to change the options.
drupal_alter('s3fs_cors_sign_request_options', $options);
if (!empty($config['cache_control_header'])) {
$options['Cache-Control'] = $config['cache_control_header'];
}
module_load_include('inc', 's3fs_cors', 's3fs_cors.post_object_v4.class');
$post_object = new S3fsCorsPostObjectV4($client, $config['bucket'], $formInputs, $options);
// Use next code with AWS SDK v3.
// $post_object = new Aws\S3\PostObjectV4($client, $config['bucket'], $formInputs, $options);
$data = array(
'inputs' => $post_object
->getFormInputs(),
'form' => $post_object
->getFormAttributes(),
// Tell our javascript the filename that Drupal ended up giving us.
'file_real' => drupal_basename($s3_key),
);
// Prepare to send JSON text to the browser.
if (ob_get_level()) {
ob_end_clean();
}
drupal_add_http_header('Content-Type', 'application/json; charset=utf-8');
print json_encode($data);
drupal_exit();
}