0

For example: There is a website which offers file downloads. The website and downloadable files are on separate servers. When a user attempts to download a file, the file server sends the file instead. The file server should not have to send the file to the website's server first before arriving at the user, since that would use double the bandwidth.

Can PHP be used to serve the file directly from the file server?

Note: a single server setup can simply use the following code from the PHP manual. I need these headers to be sent from the file server directly to the user.

<?php
$file = 'monkey.gif';

if (file_exists($file)) 
{
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}
?>
Kausheel
  • 245
  • 1
  • 2
  • 8
  • 2
    Why not redirect the user directly to the file server? Eg: he clicks a button on website1 which redirects him to: http://website2/files/foo.bar ? – posixpascal Jul 14 '14 at 07:24
  • Perhaps: http://stackoverflow.com/questions/6086231/transfer-from-server-server-client-without-download-to-server/6086311#6086311 also http://stackoverflow.com/questions/10991443/curl-get-remote-file-and-force-download-at-same-time/10993094#10993094 – Lawrence Cherone Jul 14 '14 at 07:27

3 Answers3

2

I see few possible solution to this.

1) It's mount 2nd server directory to 1st server where php is running. As result you will get file from mounted directory and pass it to user.

2) It's send to user not file content but link to download from another server. For example using redirect

header("Location: http://2nd-server-ip.com/myfile.zip");
0

Why not use cURL?

<?php

$file = 'monkey.gif';

if (file_exists($file)) {
    $ch = curl_init();
    $timeout = 5;
    $headers = array('Content-Description' => 'File Transfer',
        'Content-Type' => 'application/octet-stream',
        'Content-Disposition' => 'attachment; filename=' . basename($file),
        'Expires' => FALSE,
        'Cache-Control' => 'must-revalidate',
        'Pragma' => 'public',
        'Content-Length' => filesize($file));
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $data = curl_exec($ch);
    curl_close($ch);
    echo $data;
}
James
  • 834
  • 7
  • 27
0

Since you are planning to do this server-side through PHP, in my opinion you could do that in more than a single way.

Generally speaking the operation is made of three phases:

  1. Acquire the desired resource

  2. Read it into a string (if it is small enough)

  3. Serve it through an output stream

The difference you are looking for is in phase 1, for which I can figure out the following alternatives right now:

  • Your server and the file server share at least a part of their filesystems, e.g. with NFS. That way the file server could export the download directory, and your web server's PHP script could access the downloadable resources serving them as you were figuring out;

  • Your PHP script could access the file server's desired resource obtaining it via (S)FTP or HTTP(S) through secret (i.e. server-to-server) authentication (for example via cURL functions as correctly suggested by others) and, as a second step, serve it.

Hope this helps.

Federico Zancan
  • 4,846
  • 4
  • 44
  • 60