--- In advanced_delphi@yahoogroups.com, "Doug Hale" <del...@...> wrote:
>
> I am  having problems sending .pdf files from a CGI application.
>
> My code:
>
>     Filename := Path+Document+'.pdf';
>     Fs := TFileStream.Create(Filename, fmOpenRead, fmShareDenyNone);
>     Response.ContentType := 'application/pdf';
>     Response.ContentStream := Fs;
>
>
> The problem is that sometimes the file is not sent. The HTTP request
needs to be sent more than once to get the document actually sent.
>
> Do I need to do
>
>     Response.SendResponse;
>
> after the above code?
>
> Am I doing something I shouldn't or not doing something I should.

I don't know how to do this in Delphi, but here is some PHP code that
does what you want.  This code is used to serve up members-only and
public files, depending on the user's authentication. The files are
stored in directories that are inaccessible to the web server and are
streamed out to the browser upon request. This function also keeps track
of download counts and the last time a file was downloaded in a MySQL
database.

This function took a LOT of tweaking to get it to work reliably on
multiple browsers and file types. It now works great on all the listed
file types and has been in continuous use for several years.

The HTTP headers gave me the most headaches during development - look
closely at that part.

I do use Delphi to manage the database  end of this code. :-)

     // This function looks up a file in the filelist table and serves it
to the end-users browser
     // We send the file type along with the file binary stuff, so the
user's browser *should* open the
     // file with the correct application.

     function fetch_file($id_field, $id_value)
     {
         $ret = FILEOK;

         $link = connect();

         $q = "SELECT filename, membersonly from filelist WHERE " .
$id_field . " = '" . $id_value . "';";

         $res = mysql_query($q);
         if ($res)
         {
             if (mysql_num_rows($res) > 0)
             {
                 // just get the first match
                 $row = mysql_fetch_row($res);
                 $filename = $row[0];
                 if (($row[1] == "N") or (SecCheck())) // check user
authorization if not a public file
                 {
                     disconnectcw($link);
                     if (!is_file($filename) || connection_status() != 0)
                     {
                         // can't find the file
                             return FILEERROR;
                     }
                     // to prevent long file from getting cut off from   
//max_execution_time
                     set_time_limit(0);

                     // filenames in IE containing dots will screw up the
                     // filename unless we add this
                     //if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
                     //    $filename = preg_replace('/\./', '%2e',
$filename, substr_count($file, '.') - 1);
                     //
                     $file_extension =
strtolower(substr(strrchr($filename, "."), 1));

                     switch ($file_extension)
                     {
                         case "pdf":
                             $ctype = "application/pdf";
                             break;
                         case 'txt':
                             $ctype = "text/plain";
                             break;
                         case "exe":
                             $ctype = "application/octet-stream";
                             break;
                         case "zip":
                             $ctype = "application/zip";
                             break;
                         case "doc":
                             $ctype = "application/msword";
                             break;
                         case "xls":
                             $ctype = "application/vnd.ms-excel";
                             break;
                         case "ppt":
                             $ctype = "application/vnd.ms-powerpoint";
                             break;
                         case "gif":
                             $ctype = "image/gif";
                             break;
                         case "png":
                             $ctype = "image/png";
                             break;
                         case "mp3":
                             $ctype = "audio/mp3";
                             break;
                         case "jpe":
                         case "jpeg":
                         case "jpg":
                             $ctype = "image/jpg";
                             break;
                         default:
                             $ctype = "application/force-download";
                     }

                     header("Pragma: public"); // required
                     if (ini_get('zlib.output_compression'))
                         ini_set('zlib.output_compression', 'Off');
                     header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); //
Date in the past to make cache expire
                     header("Cache-Control: must-revalidate,
post-check=0, pre-check=0");
                     header("Cache-Control: private", false);
                     header("Content-Type: $ctype");
                     header("Content-Disposition: attachment; filename="
. basename($filename) . ";");
                     header("Content-Transfer-Encoding: binary");
                     header("Content-Length: " . filesize($filename));
                     if($file = fopen($filename, 'rb'))
                     {
                         $link = connect();
                         $q = "update filelist set
downloadcount=(downloadcount+1), lastdownload=NOW() WHERE " . $id_field
. " = '" . $id_value . "';";
                         $res = mysql_query($q);
                         disconnectcw($link);

                         // Stream the file out to the guy's browser, 8K
at a time...
                         while( (!feof($file)) &&
(connection_status()==0) )
                         {
                             print(fread($file, 8192));
                             flush();
                         }
                         fclose($file);
                     }

                     if ((connection_status() == 0) and
!connection_aborted())
                     {
                         return FILEOK;
                     }
                     else
                         return     FILEERROR;
                 }
                 else
                     return SECERROR;
             }
             else
             {
                 return FILEERROR;
             }
         }
         else
         {
             return DBERROR;
         }
     }


Reply via email to