Jump to content

Header Download won't work through site link


Exoon

Recommended Posts

Hello,

 

I want to have a simple script to hide the true URL to my files. Ive made the script and it works fine when i directly access it through domain.com/hd-file.php

 

However when i visit it through index.php?page=hd-file it downloads a file which is the right size etc but the file is always corrupt ?

 

Can't work it out, Heres the code:

 

hd-file.php

<?php
$file = $_GET['file'];
$path = '/home/username/public_html/ben-lightsabre3.avi'; // the file made available for download via this PHP file
$mm_type="application/octet-stream"; // modify accordingly to the file type of $path, but in most cases no need to do so

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");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");

readfile($path); // outputs the content of the file

exit();

 

 

Heres the code im using on my index to process the index.php?page= stuff

<?
if(isSet($pageWeb)){
	if (!(strpos($pageWeb, "http") === false)){
	 echo "not allowed";
	}else{
		include("$pageWeb.php");
	}
} elseif(isSet($p_page)){

if (!(strpos($p_page, "http")===false)){
		echo "not allowed";
	}else{
		include("$p_page.php");
	}
} else {
	include("main.php");
}
}
?>

 

Thanks in advance!

Link to comment
Share on other sites

Hi,

 

Thanks for the reply. I tried doing what you said but it didn't fix the video being corrupt when downloading using the index.php?page=hd-file link

 

What exactly doing what you said change? My script worked the same when it was in quotes from what i can see.

 

Cheers

Link to comment
Share on other sites

Your index.php vars in quotes how will is be included ?

 

var has quotes arround

include("$p_page.php");

 

This is perfectly valid, and looks a lot better than the way you suggested.

http://us3.php.net/manual/en/language.types.string.php

http://us3.php.net/manual/en/language.types.string.php#language.types.string.syntax.double

http://us3.php.net/manual/en/language.types.string.php#language.types.string.parsing

 

 

OP: Do you have error reporting on? What is the point of $file = $_GET['file']; ? Where does $pageWeb and $p_page come from?

Link to comment
Share on other sites

Hi,

 

Yes i have error reporting on, I don't get any errors. The PHP file starts download the file fine when accessed both ways, The only difference is when accessed directly using hd-file.php in the browser, This video plays. When accessed using index.php?page=hd-file, It doesn't play.

 

$file = $_GET['file']; was me getting ahead of myself, Not doing anything untill i can get a basic download working.

 

With pageWeb i have $pageWeb = $_REQUEST['page']; at the top of my index to get the page info?

 

My host gave me the script as they said my one before wasent very secure and would allow people to put data from elsewhere onto my site.

 

Not 100% what $p_page is for.

 

Cheers

 

 

Link to comment
Share on other sites

My guess is something else is echo'd, like an error message, before the file is output.

 

The easiest way to check this would be to do something like this:

 

<?php

if( ob_get_level() )
die( 'Output buffering is active. This needs to be fixed' );
if( headers_sent() )
die( 'Headers already sent. This needs to be fixed.' );

$path = '/home/username/public_html/ben-lightsabre3.avi'; // the file made available for download via this PHP file
$mm_type="application/octet-stream"; // modify accordingly to the file type of $path, but in most cases no need to do so

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");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");

readfile($path); // outputs the content of the file

exit();

?>

 

Also, please post your entire index.php file. If it works when you access the page directly, there's obviously not an issue with that script, but instead the script you're using to load it through GET variables

Link to comment
Share on other sites

Hello,

 

I get an error with your script: Output buffering is active. This needs to be fixed

 

 

index.php

<?php
include("config.php");
$pageWeb = $_REQUEST['page'];
session_start();
$loggedin = $_SESSION['loggedin']; // Are they loggedin?

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Site Tagline Here!</title>
<link href="/style.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div id="wrapper"><!-- Open Container -->
<div id="header-banner"><!--Open Header Banner -->

<div id="login-wrapper1">
<?php
if($loggedin == "1") {
  echo "<div style=\"text-align:center; margin-top:10px;\">Welcome back $_SESSION[username], <a href=\"/logout/\">Logout</a></div>";
}else {
?>
<form action="/login/" method="post">
<div class="username">
        <div class="label">Username:</div><input name="username" type="text" />
    </div>
    <div class="password">
        <div class="label">Password:</div><input type="password" name="password" type="text" />
    </div>
    <div class="submit">
    	<input name="submit" type="submit" value="Login" />
    </div>
</form>
<form action="/join/" method="post">
    <div class="submit">
    	<input name="submit" type="submit" value="Join" />
    </div>
</form>
<?
}
?>
</div>


</div> <!-- Close Header Banner -->
<div id="header-nav"><!--Open Header Nav -->
    <div class="button-wrapper"><!--Open Button Wrapper -->
        <div class="button-home" onclick="location.href='/';" style="cursor: pointer;"></div>
        <?php
          if ($loggedin == "1") {
        ?>
        <div class="button-videos" onclick="location.href='/videos/';" style="cursor: pointer;"></div>
        <div class="button-search" onclick="location.href='/search/';" style="cursor: pointer;"></div>
        <?
        } else {
        ?>
        <div class="button-register" onclick="location.href='/register/';" style="cursor: pointer;"></div>
        <div class="button-join" onclick="location.href='/join/';" style="cursor: pointer;"></div>
        <?
        }
        ?>
        <div class="button-hosting" onclick="location.href='/hosting/';" style="cursor: pointer;"></div>
        <?php
        if($loggedin == "1") {
        ?>
        <div class="button-settings" onclick="location.href='/settings/';" style="cursor: pointer;"></div>
        <?php
	} else {
	?>
        <div class="button-members" onclick="location.href='/login/';" style="cursor: pointer;"></div>
        <?php
	}
	?>
    </div><!--Close Button Wrapper -->
</div><!--Close Header Nav-->

<div id="content-wrapper"> <!-- Open Content Wrapper -->

<?

if(isSet($pageWeb)){
	if (!(strpos($pageWeb, "http") === false)){
	 echo "not allowed";
	}else{
		include($pageWeb.".php");
	}
} elseif(isSet($p_page)){

if (!(strpos($p_page, "http")===false)){
		echo "not allowed";
	}else{
		include($p_page.".php");
	}
} else {
	include("main.php");
}
?>
<div id="footer"><img border="0" src="/images/footer-secure.png" /></div>

</div> <!-- Close Content Wrapper -->

</div><!-- Close Container -->
</body>
</html>

Link to comment
Share on other sites

Keep your logic and your business SEPARATE :D

 

Do you want the easy fix, or the right fix?

 

easy:

<?php

// while output buffering is on
while( ob_get_level() )
// turn it off, and destroy everything in it, rather than outputting it
ob_end_clean();

$file = $_GET['file'];
$path = '/home/username/public_html/ben-lightsabre3.avi'; // the file made available for download via this PHP file
$mm_type="application/octet-stream"; // modify accordingly to the file type of $path, but in most cases no need to do so

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");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");

readfile($path); // outputs the content of the file

exit();

Link to comment
Share on other sites

I think he meant to say logic and presentation. Code that DOES stuff goes first, then anything that displays, echos, makes it look pretty comes second. Read about Smarty or another templating engine to understand.

Link to comment
Share on other sites

I worded that wrong, I mean presentation and logic separate. Put your HTML in it's own files, and include it when needed. Here's how clean your index.php COULD look.

 

<?php
include("config.php");
$pageWeb = $_REQUEST['page'];
session_start();
$loggedin = $_SESSION['loggedin']; // Are they loggedin?

// check if an invalid or insecure page has been given
// i added in an extra check for you
if(!isSet($pageWeb) || strpos($pageWeb, "http") !== false){
// if it's invalid, set to default
$pageWeb = 'main';
}

// check if there's a page where we dont want to output any html
if( $pageWeb == 'hd-file' ) {
include('hd-file.php');
exit;
} else {
include('html_header.php');
if($loggedin == "1") {
	include('html_userwelcome.php');
	include('html_usernav.php');
}else {
	include('html_login.php');
	include('html_loginnav.php');
}
// by forcing basename, you prevent people accessing outside files
// using ?page=../outsidefile.php
include(basename($pageWeb).'.php');
include('footer.php');
}

?>

 

The right fix would be to turn off output buffering by default, and re-arrange your logic, like I've done above, to never output the HTML in the first place when you want to send a file to the browser.

 

The reason you're doing it the 'wrong' way with that fix is you're still attempting to output stuff you don't want before you output your file. My two-line addition simply wipes the buffers clean and turns them off before outputting the file.

 

Hope this helps.

Link to comment
Share on other sites

Ive put the download stuff to the top and it works perfectly, can't thank you enough jesirose and xyph.

 

I see what you mean about how neat it can look, Will definitely spend some time sorting out my page now.

 

Thanks so much!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.