file_transfer

5 file.inc file_transfer($source, $headers)
6 file.inc file_transfer($source, $headers)
7 file.inc file_transfer($uri, $headers)
8 file.inc file_transfer($uri, $headers)

Transfer file using http to client. Pipes a file through Drupal to the client.

Parameters

$source File to transfer.:

$headers An array of http headers to send along with file.:

Related topics

1 call to file_transfer()

File

includes/file.inc, line 859
API for handling file uploads and server file management.

Code

function file_transfer($source, $headers) {
  if (ob_get_level()) {
    ob_end_clean();
  }

  // IE cannot download private files because it cannot store files downloaded
  // over https in the browser cache. The problem can be solved by sending
  // custom headers to IE. See http://support.microsoft.com/kb/323308/en-us
  if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) {
    drupal_set_header('Cache-Control: private');
    drupal_set_header('Pragma: private');
  }

  foreach ($headers as $header) {
    // To prevent HTTP header injection, we delete new lines that are
    // not followed by a space or a tab.
    // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
    $header = preg_replace('/\r?\n(?!\t| )/', '', $header);
    drupal_set_header($header);
  }

  $source = file_create_path($source);

  // Transfer file in 1024 byte chunks to save memory usage.
  if ($fd = fopen($source, 'rb')) {
    while (!feof($fd)) {
      print fread($fd, 1024);
    }
    fclose($fd);
  }
  else {
    drupal_not_found();
  }
  exit();
}

Comments

A note about the headers.

Unlike some other places in Drupal that use an associative array for the header information, 'file_transfer' needs a sequential array. Sorta like this:

<?php
file_transfer
(file_directory_path().'/'.$filename, array('Content-Type: octet/stream','Content-Disposition: attachment; filename="'.$filename.';',
       
'Content-Length: '.filesize(file_directory_path().'/'.$filename),
        ));
?>

File path

After a lot of trying, I realized that for the first argument, I had to pass the full filesystem path of the file, not just the path relative to base_path(). For example:

<?php
file_transfer
($_SERVER['DOCUMENT_ROOT'] . base_path() . file_directory_path() . '/some-file.zip', $headers);
?>

File path

Maybe it is obvious, but I spent few hours before I realised that the file should be in the file directory of drupal (sites/default/files)... Hope it helps.

Why this function has exit in the end.

When file transfer is done I need to delete the file or someone wants to do something just after the downloading the file, then in that case what has to done.

Login or register to post comments