File outside of web directory is corrupt or truncated
I am trying to use a handler to serve a file that is outside of my web directory and I am having some issues. I want to do checks in the handler and need to be able to run a query but as soon as I add a line of code other than what I have shown, I get the error The image “http://localhost/xampp/site_name/image_handler.php?ID=d5xa24tdufoseg868r66yjz5sr19u41i” cannot be displayed because it contains errors. In firefox I checked the console in firebug and it says image is corrupt or truncated. However if I leave the base code I have shown it just serves the image. Anyone know why this could be?
EDIT: Showing all code
<?php
i开发者_开发百科nclude("roc/include/connection.php");
$db = new PDOConnectionFactory();
$conn = $db->getConnection();
//prepare for utf8 characters
$sql = 'SET NAMES utf8';
$stmt = $conn->prepare($sql);
$result=$stmt->execute();
$sql = 'SET CHARACTER SET utf8';
$stmt = $conn->prepare($sql);
$result=$stmt->execute();
//**************************
if (! preg_match("/^[-a-z.-@,'s]*$/i",$_GET['ID']))
{
die('No illegal characters');
}
else
$empty=strlen($_GET['ID']);
if ($empty==0)
{
die('The text field cannot be empty');
}
else
{
$ID = $_GET['ID'];
if (strlen($_GET['ID'])>35){
exit("error");
}
}
$sql="SELECT file_name FROM video WHERE vid_id=?";
$stmt=$conn->prepare($sql);
$result=$stmt->execute(array($ID));
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$file_name = $row['file_name']."[img-004].jpg";
}
echo $path="/home/g/Desktop/processed/".$file_name."";
//check if image is readible and type
if (is_readable($path)) {
header('Content-Length: '.filesize($path)); // provide file size
header("Expires: -1");
header('Content-Type: image/jpeg');
$content=file_get_contents('/home/g/Desktop/processed/986861d331e8b4b4eacee5cb7aed494a[img-004].jpg');
}
else {
error_log("Can't serve image: $file_name");
}
?>
HTML OUTPUT
<img src="http://localhost/xampp/site_name/image_handler.php?ID=d5xa24tdufoseg868r66yjz5sr19u41i" alt="The image “http://localhost/xampp/site_name/image_handler.php?ID=d5xa24tdufoseg868r66yjz5sr19u41i” cannot be displayed because it contains errors.">
If you do a echo "test"
prior to sending headers... things will go wrong.
If you send an echo "test"
and your headers say that you're sending an image... things will go wrong.
Code is working.
If you add any additional data to image data your image will get corrupt. If you are outputting an image you better not to echo anything other than the image. The only way around might be writing whatever you want to write on the image. You can use GD functions to do that. There is another way that I might advice not to, you may add whatever you like to end of the image without getting an error. But thats not guaranteed.
PS: You can still run more code than that apart from echo'ing on the screen.
I don't know the code you are adding to do your 'checks' but as per the manual: Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP.
Maybe you would be better off putting that image in a buffer:
<?php
// Code that checks out whatever ..
// more checks
ob_start();
myClass::renderPng(); //header("Content-Type: image/png"); in here
$pngString = ob_get_contents();
ob_end_clean();
?>
What do you want your script to output if there is an error? HTML? A special error image?
<?php
$content = readfile('/home/g/Desktop/processed/986861d331e8b4b4eacee5cb7aed494a[img-004].jpg');
// Did readfile succeed?
// Do db query.
// Do some other checks.
// Now output something to browser.
if ($are_we_okay == true) {
header("Content-type: image/jpeg");
echo $content;
} else {
header("Content-type: text/html");
echo "<b>Failed!</b>";
}
?>
精彩评论