I am writing a webpage for client to download file. In order to restrict who is able to download what, I don't provide the direct link of the file to the client. Instead, I put the files out of the web document root, and use a PHP page to open the files and stream to client.

First, filelist.php provides a list of the downloadable files. When client wants to download a file, he clicks on the link "downloadfile.php?actioinfile=filename"

Below is the code of downloadfile.php

<?php
session_start();
include("checksession.php");
header("Content-Type: application/octat-stream");
header("Content-Disposition: attachment; filename=$actionfile");

include("../global.php");

if($sourcefp=@fopen("$file_folder_path/$user_folder_path/$actionfile","rb"))
{
	ob_start();

	while(!feof($sourcefp)) 
	{
		$buffer = fread($sourcefp, 16384);
		echo $buffer;
		flush();
	}
	fclose($sourcefp);
	unset($sourcefp);
	ob_end_flush();
}

?>

Everything worked fine when I tested it with my home computer as client. I clicked on the link, a message box popped up asking me to save a file with name filename, then I can download the file.

But when I tested it with my office computer, which resides within an intranet and uses a proxy server to access the world outside, something strange happened. No matter which link I clicked (different links should download different files), I was always prompted to save a file with name filelist.php. And then after downloading, the downloaded file is the html code outputted by filelist.php.

I really don't understand why....I was prompted to save a file, that means I was successfully redirected to downloadfile.php, and the two "header" lines had taken effect. But how come the file streamed to me would have become filelist.php??? And why would this problem happens only when I use a client computer behind a proxy server??

    It should be an octEt stream, but other than that, I see no errors (well, except that $actionfile isn't ever set).

      Originally posted by Mordecai
      It should be an octEt stream, but other than that, I see no errors (well, except that $actionfile isn't ever set).

      Oh, I will try to use "octet stream" then.

      $actionfile is posted to downloadfile.php when client clicks on the link "downloadfile.php?actionfile=filename". This should work.......right? Or this will not work under certain circumstances??

        Well, I'm never crazy about putting actual file names into query strings. At mimimum... I'd place a simple array in my filelist page and give each file name it's own id. this way, the script calls an id rather than a file path. You might want to make sure that whatever file is called via the query string, that a user cannot maliciously tamper with the data. Make sure they don't request any files beginning with "." or ".." and such. Just some paranoia for you...

        -heyrad

          Originally posted by heyrad
          Well, I'm never crazy about putting actual file names into query strings. At mimimum... I'd place a simple array in my filelist page and give each file name it's own id. this way, the script calls an id rather than a file path. You might want to make sure that whatever file is called via the query string, that a user cannot maliciously tamper with the data. Make sure they don't request any files beginning with "." or ".." and such. Just some paranoia for you...

          -heyrad

          thx for reminding me. I will check for some "meaningful" filenames then.

          I tried to change the header to "octet", but still the same....

            No idea on what cause the error.

            But are you sure whether it is the server-side problem or client-side problem?

            Have you tried connecting through a proxy in your home PC?

            And I don't know much about the function 'ob_start()'.

            Why do you use 'ob_start' here? What is your purpose of holding the data in buffer until you finished reading the file?

            To my understanding, the data will not be send to user until you call 'ob_end_flush()'. Then it may be a long time that the proxy server receive nothing but holding the connection if the filesize is large. What will be the action of that proxy server holding the connection but receive nothing? I don't know.

            Maybe you can trace out the cause from the above 2 directions.

              Write a Reply...