Skip navigation


6 file_download()
7 file_download()

Menu handler for private file transfers.

Call modules that implement hook_file_download() to find out if a file is accessible and what headers it should be transferred with. If one or more modules returned headers the download will start with the returned headers. If a module returns -1 drupal_access_denied() will be returned. If the file exists but no modules responded drupal_access_denied() will be returned. If the file does not exist drupal_not_found() will be returned.

See also


Related topics

1 call to file_download()

7 string references to 'file_download'


drupal/includes/, line 1913
API for handling file uploads and server file management.


function file_download() {
  // Merge remainder of arguments from GET['q'], into relative file path.
  $args = func_get_args();
  $scheme = array_shift($args);
  $target = implode('/', $args);
  $uri = $scheme . '://' . $target;
  if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
    // Let other modules provide headers and controls access to the file.
    // module_invoke_all() uses array_merge_recursive() which merges header
    // values into a new array. To avoid that and allow modules to override
    // headers instead, use array_merge() to merge the returned arrays.
    $headers = array();
    foreach (module_implements('file_download') as $module) {
      $function = $module . '_file_download';
      $result = $function($uri);
      if ($result == -1) {
        return drupal_access_denied();
      if (isset($result) && is_array($result)) {
        $headers = array_merge($headers, $result);
    if (count($headers)) {
      file_transfer($uri, $headers);
    return drupal_access_denied();
  return drupal_not_found();