Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

MatchFiles applied to only files of a certain size 1

Status
Not open for further replies.

phripley

Programmer
Jun 6, 2007
6
0
0
US
For a photo gallery-type project I would like to have certain images served as attachments (downloaded) and other served inline as normal.

The rule I have in mind is as follows:

If:

A. the file is over 500KB in size

AND

B. And its name does not end with either _medium.jpeg or _thumb.jpeg

Then:

Header Set Content-Disposition attachment
ForceType application/octet-stream


This is in Apache Server 2.2


I know how to handle condition B, above with <FilesMatch> and a little bit of REGEX.

But don't know how to approach capturing the file size, in condition A.

Any pointers?
 
Hi

As far as I know, there is no way to do that in the web server itself. I would do it like this :
Code:
RewriteCond %{REQUEST_URI} !.*_(medium|thumb)\.jpeg^
RewriteRule .* /getimage.php?filename=%{REQUEST_URI}
Code:
<?php
if (filesize($_GET['filename'])>500*1024) {
  header('Content-Disposition: attachment');
  header('Content-type: application/octet-stream');
}
readfile($_GET['filename']);
?>

Feherke.
 
Thanks feherke!

I was hoping to not have to resort to php, but if there's no other way, yours looks like a good solution.
 
Hi

Yes, but note that I just kept it simple, so you have to add checking for the GET parameter and the existence of the file.
Code:
<?php
$filename=$_GET[[i]'filename'[/i]];
$ok=file_exists($filename);
[b]if[/b] ($ok) {
  $filepath=pathinfo($filename);
  $ok=$filepath[[i]'dirname'[/i]]==[i]'/images'[/i] && $filepath[[i]'extension'[/i]]==[i]'jpeg'[/i];
}
[b]if[/b] ($ok) {
  [b]if[/b] (filesize($filename)>500*1024) {
    header([i]'Content-Disposition: attachment'[/i]);
    header([i]'Content-type: application/octet-stream'[/i]);
  }
  readfile($filename);
  [b]return[/b];
}
header([i]'HTTP/1.0 404 Not Found'[/i]);
?>
<html>
<head>
<title>Error 404</title>
<head>
<body>
<h1>Error 404 - Not Found</h1>
<p>The requested file, "<?php echo $filename; ?>", does not exists.</p>
</body>
</html>
The above script will send a 404 Not Found response if it is requested a file outside of the /images directory or with other extension then jpeg.

Note that you may have to change the path of the $filename to the local filesystem path. Or just pass [tt]REQUEST_FILENAME[/tt] as parameter from the [tt]RewriteRule[/tt].

Feherke.
 
Thanks again feherke!

My script is posted below. Made a couple of small modifications.

My concern with this tho is that someone might manipulate the request string to get access to files that are not meant to be accessed (using ../../ or some such)

I *think* my script limits them to only accessing JPEGs and only accessing the images/press directory. But I thought I would post here to see if anyone else had any security tips...

<?php

/*

*** getimage ***

phr 14 june 2007

the purpose of this script is to serve large jpegs as downloads, while
smaller jpegs are served inline as usual.

it is intended to be used in conjunction with an htaccess rewrite


*/

$pathinfo = pathinfo(__FILE__);
$hostroot = $pathinfo['dirname']; // on the live site the value is /
$filename= $_GET['filename']; // grab the value of the requested file from the url

$ok=file_exists($hostroot . $filename);

// for security reasons we want to allow this script to only function inside certain directories
$safedirectory = "$hostroot/images/press";

if ($ok) { // the file exists
$filepath = pathinfo($hostroot . $filename);
if (strpos($filepath['dirname'],"$safedirectory") === "0" AND ($filepath['extension']=='jpeg' OR $filepath['extension']=='jpg')){
// the file is in the images directory, and is a jpeg
$ok = true;
}
}

if ($ok) { // the file is in the images directory, and is a jpeg
$filesize = filesize($hostroot . $filename);
if ($filesize > 500*1024) { // image is larger than 500KB
header('Content-Disposition: attachment');
header('Content-type: application/octet-stream');
header ("Content-Length: $filesize");
}
else { // image is smaller than 500KB
header('Content-type: image/jpeg');
header ("Content-Length: $filesize");
}
readfile($hostroot . $filename);
return;
}
header('HTTP/1.0 404 Not Found');

?>
<html>
<head>
<title>Error 404</title>
<head>
<body>
<h1>Error 404 - Not Found</h1>
<p>The requested file, "<?php echo $filename; ?>", does not exists.</p>
</body>
</html>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top