Solved

Header/readfile does not work when trying to display image outside of website root

Posted on 2013-01-01
8
322 Views
Last Modified: 2013-01-04
Hi,

I'm using this code to open an image saved outside of web root (home/kenneth/uploads/...)
It works fine in both IE and FF, but it does not work in Chrome - it just keep loading.

# Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".$file['original_filename']);
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($absolute_path));

ob_clean();
flush();

# Read the file from disk
readfile($absolute_path);

Open in new window

$file['download_path'] = "http://".$file['hostname']."/download.php?token=".$token;

<img style="margin: 15px; max-width: 870px" src="<?php echo $file['download_path']; ?>" alt="<?php echo $file['original_filename']; ?>" />

Open in new window

0
Comment
Question by:kgp43
  • 4
  • 4
8 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38734458
What are you trying to accomplish?  Is it to render an image in the browser viewport or force a download?
0
 

Author Comment

by:kgp43
ID: 38734481
Display an image located outside public_html

Ex.

<img src="/photo.php?fileid=xxxx" />

Photo.php

# Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".$file['original_filename']);
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($absolute_path));

ob_clean();
flush();

# Read the file from disk
readfile($absolute_path);

Open in new window


The image appear correctly in both Firefox and IE, but not in Chrome. Chrome just keep loading, no image appears.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38734528
You may have a lot more headers than you need.  This article describes how I do it.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_10065-Adding-a-Watermark-to-an-Image.html

IIRC the only header you really need is Content-type
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38734531
I am also a little suspicious of this.  Why do you use that function?
http://php.net/manual/en/function.ob-clean.php
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:kgp43
ID: 38734588
Hi Ray,

Does not matter what I do, nothing loads in Chrome for me.
http://fs01.imgdrive.com/download.php?token=3L9QZB

header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".$file['original_filename']);
header('Content-Type: '.$file['mimetype']);

# Read the file from disk
readfile($absolute_path);

Open in new window


I removed ob_flush and cleaned up the headers. Seems I need the extra two or it's not possible to save the image with original filename when right-clicking (save as).
0
 

Author Comment

by:kgp43
ID: 38734610
More error checking.
http://fs01.imgdrive.com/test.php

$absolute_path = "/home/fs01/uploads/2012/12/31/v3hbspfc9d_image.jpg";

header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".basename($absolute_path));
header('Content-Type: application/octet-stream');

# Read the file from disk
readfile($absolute_path);

Open in new window


Seems the code above start image download.
Going to see if the rest works with it.
0
 

Author Comment

by:kgp43
ID: 38734647
Works not, not sure what the problem was.

header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".basename($absolute_path));
header('Content-Type: '.$file['mimetype']);

# Read the file from disk
readfile($absolute_path);

Open in new window

0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 38734694
Probably just getting rid of the inappropriate headers like Application/Octet Stream was all that was needed.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

This article discusses four methods for overlaying images in a container on a web page
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now