Connecting Tech Pros Worldwide Forums | Help | Site Map

Pass Through Any File?

Smitro
Guest
 
Posts: n/a
#1: Aug 22 '05
Hi,

I know php is able to pass a file through, but I
have never done it before.

This is my dilema, I have writen a secure site.
Everyone must login to see the data. But I would
like to secure pictures to start with, but also
other files that people upload. The problem is
that people can upload anything, it's not limited
to to certain file types. Is it possible to create
a php file that will pass any file type through it
from a secured directory outside of the web root
directory. So basicly I can stick the security on
one php file for all the other files that are
uploaded over time. Basicly to stop people from
browsing directly to a file without being logged in.

Hopefully that made sence.

Alvaro G Vicario
Guest
 
Posts: n/a
#2: Aug 22 '05

re: Pass Through Any File?


*** Smitro wrote/escribió (Mon, 22 Aug 2005 17:11:05 +1000):[color=blue]
> to to certain file types. Is it possible to create
> a php file that will pass any file type through it
> from a secured directory outside of the web root
> directory.[/color]

Yes.

The functions you need are:

mime_content_type()
header()
readfile()

You have an example at www.php.net/header


--
-- Álvaro G. Vicario - Burgos, Spain
-- http://bits.demogracia.com - Mi sitio sobre programación web
-- Don't e-mail me your questions, post them to the group
--
Smitro
Guest
 
Posts: n/a
#3: Aug 23 '05

re: Pass Through Any File?


Thanks for the reply.

I tried out this example. (you didn't point to exactly which example
you were refering to)

<?php

function dl_file($file){

//First, see if the file exists
if (!is_file($file)) { die("<b>404 File not found!</b>"); }

//Gather relevent info about file
$len = filesize($file);
$filename = basename($file);
$file_extension = strtolower(substr(strrchr($filename,"."),1));

//This will set the Content-Type to the appropriate setting for the
file
switch( $file_extension ) {
case "pdf": $ctype="application/pdf"; 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 "jpeg":
case "jpg": $ctype="image/jpg"; break;
case "mp3": $ctype="audio/mpeg"; break;
case "wav": $ctype="audio/x-wav"; break;
case "mpeg":
case "mpg":
case "mpe": $ctype="video/mpeg"; break;
case "mov": $ctype="video/quicktime"; break;
case "avi": $ctype="video/x-msvideo"; break;

//The following are for extensions that shouldn't be downloaded
(sensitive stuff, like php files)
case "php":
case "htm":
case "html":
case "txt": die("<b>Cannot be used for ". $file_extension ."
files!</b>"); break;

default: $ctype="application/force-download";
}

//Begin writing headers
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");

//Use the switch-generated Content-Type
header("Content-Type: $ctype");

//Force the download
$header="Content-Disposition: attachment; filename=".$filename.";";
header($header );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".$len);
@readfile($file);
exit;
}

?>

Fixefox ask if you want to save or open them, but in IE files are just
read straight into the browser (billions of weird characters). I'm
guessing thats because the headers havn't been read properly. I have
tried changeing headers and what not after reading other posts but
can't seem to work it out. Although jpg files work. Interesting though,
I put a PDF file through it and it came out all weird, but when I went
to the properties of the page it said it was an Acrobat PDF file. Any
suggestions on where I've gone wrong?

Smitro
Guest
 
Posts: n/a
#4: Aug 23 '05

re: Pass Through Any File?


Unbelievable!

I've been working on this all day, and for some reason it just all of a
suddern worked. No idea how or what... but It worked. I just tried the
above script again in IE and it just worked. No idea what happened.

Alvaro G Vicario
Guest
 
Posts: n/a
#5: Aug 23 '05

re: Pass Through Any File?


*** Smitro wrote/escribió (22 Aug 2005 17:07:14 -0700):[color=blue]
> I tried out this example. (you didn't point to exactly which example
> you were refering to)[/color]

There's only one related to this:

<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?>

[color=blue]
> $file_extension = strtolower(substr(strrchr($filename,"."),1));
>
> //This will set the Content-Type to the appropriate setting for the
> file
> switch( $file_extension ) {
> case "pdf": $ctype="application/pdf"; break;[/color]

Apart from the fact that file extension is sometimes unreliable, it's crazy
to hardcode all possible extensions. Why don't you try mime_content_type()?


[color=blue]
> Fixefox ask if you want to save or open them, but in IE files are just
> read straight into the browser (billions of weird characters).[/color]

Your code looks fine to me. Unluckily, Internet Explorer is a deprecated
buggy browser that'll force you to many workarounds. Some people recommend
to use a generic content type to force download:

application/octet-stream

Also, check whether you're using sessions, cookies or something else that's
adding headers: IE often gets confused.


--
-- Álvaro G. Vicario - Burgos, Spain
-- http://bits.demogracia.com - Mi sitio sobre programación web
-- Don't e-mail me your questions, post them to the group
--
Closed Thread