Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

header trouble

runtime header

  • Please log in to reply
3 replies to this topic

#1 MeekLogic

MeekLogic

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 177 posts
  • Location:Fresno, CA
  • Programming Language:C#, PHP, JavaScript, PL/SQL, Visual Basic .NET, Lua

Posted 06 February 2012 - 05:07 AM

Says headers are already sent out but can't find where. Heres output http://tlokzz.info/u...ad.php?app_id=1

This is the script
<?php
require("database.class.php");

// db init
$db = new Database("localhost", "", "", "");
$db->connect();

// parse get vars
if (!isset($_GET['app_id'])) {
die("error: no app_id");
}
$id = $db->escape($_GET['app_id']);

// get app data
$app = array();
$app = $db->query_first("SELECT * FROM apps WHERE id='" . $id . "'");

// add one to download count
$data = array();
$data['downloads'] = $app['downloads']++;
$db->query_update("apps", $data, "id='" . $id . "'");

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($app['download_link']));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($app['download_link']));
ob_clean();
flush();
readfile($app['download_link']);
exit;
?>


This is database.class.php
<?php
# Name: Database.class.php
# File Description: MySQL Class to allow easy and clean access to common mysql commands
# Author: ricocheting
# Web: http://www.ricocheting.com/
# Update: 2010-05-08
# Version: 2.2.5
# Copyright 2003 ricocheting.com


/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/



//require("config.inc.php");
//$db = new Database(DB_SERVER, DB_USER, DB_PASS, DB_DATABASE);


###################################################################################################
###################################################################################################
###################################################################################################
class Database {


var $server = ""; //database server
var $user = ""; //database login name
var $pass = ""; //database login password
var $database = ""; //database name
var $pre = ""; //table prefix


#######################
//internal info
var $error = "";
var $errno = 0;

//number of rows affected by SQL query
var $affected_rows = 0;

var $link_id = 0;
var $query_id = 0;


#-#############################################
# desc: constructor
function Database($server, $user, $pass, $database, $pre=''){
$this->server=$server;
$this->user=$user;
$this->pass=$pass;
$this->database=$database;
$this->pre=$pre;
}#-#constructor()


#-#############################################
# desc: connect and select database using vars above
# Param: $new_link can force connect() to open a new link, even if mysql_connect() was called before with the same parameters
function connect($new_link=false) {
$this->link_id=@mysql_connect($this->server,$this->user,$this->pass,$new_link);

if (!$this->link_id) {//open failed
$this->oops("Could not connect to server: <b>$this->server</b>.");
}

if(!@mysql_select_db($this->database, $this->link_id)) {//no database
$this->oops("Could not open database: <b>$this->database</b>.");
}

// unset the data so it can't be dumped
$this->server='';
$this->user='';
$this->pass='';
$this->database='';
}#-#connect()


#-#############################################
# desc: close the connection
function close() {
if(!@mysql_close($this->link_id)){
$this->oops("Connection close failed.");
}
}#-#close()


#-#############################################
# Desc: escapes characters to be mysql ready
# Param: string
# returns: string
function escape($string) {
if(get_magic_quotes_runtime()) $string = stripslashes($string);
return @mysql_real_escape_string($string,$this->link_id);
}#-#escape()


#-#############################################
# Desc: executes SQL query to an open connection
# Param: (MySQL query) to execute
# returns: (query_id) for fetching results etc
function query($sql) {
// do query
$this->query_id = @mysql_query($sql, $this->link_id);

if (!$this->query_id) {
$this->oops("<b>MySQL Query fail:</b> $sql");
return 0;
}

$this->affected_rows = @mysql_affected_rows($this->link_id);

return $this->query_id;
}#-#query()


#-#############################################
# desc: fetches and returns results one line at a time
# param: query_id for mysql run. if none specified, last used
# return: (array) fetched record(s)
function fetch_array($query_id=-1) {
// retrieve row
if ($query_id!=-1) {
$this->query_id=$query_id;
}

if (isset($this->query_id)) {
$record = @mysql_fetch_assoc($this->query_id);
}else{
$this->oops("Invalid query_id: <b>$this->query_id</b>. Records could not be fetched.");
}

return $record;
}#-#fetch_array()


#-#############################################
# desc: returns all the results (not one row)
# param: (MySQL query) the query to run on server
# returns: assoc array of ALL fetched results
function fetch_all_array($sql) {
$query_id = $this->query($sql);
$out = array();

while ($row = $this->fetch_array($query_id)){
$out[] = $row;
}

$this->free_result($query_id);
return $out;
}#-#fetch_all_array()


#-#############################################
# desc: frees the resultset
# param: query_id for mysql run. if none specified, last used
function free_result($query_id=-1) {
if ($query_id!=-1) {
$this->query_id=$query_id;
}
if($this->query_id!=0 && !@mysql_free_result($this->query_id)) {
$this->oops("Result ID: <b>$this->query_id</b> could not be freed.");
}
}#-#free_result()


#-#############################################
# desc: does a query, fetches the first row only, frees resultset
# param: (MySQL query) the query to run on server
# returns: array of fetched results
function query_first($query_string) {
$query_id = $this->query($query_string);
$out = $this->fetch_array($query_id);
$this->free_result($query_id);
return $out;
}#-#query_first()


#-#############################################
# desc: does an update query with an array
# param: table (no prefix), assoc array with data (doesn't need escaped), where condition
# returns: (query_id) for fetching results etc
function query_update($table, $data, $where='1') {
$q="UPDATE `".$this->pre.$table."` SET ";

foreach($data as $key=>$val) {
if(strtolower($val)=='null') $q.= "`$key` = NULL, ";
elseif(strtolower($val)=='now()') $q.= "`$key` = NOW(), ";
elseif(preg_match("/^increment\((\-?\d+)\)$/i",$val,$m)) $q.= "`$key` = `$key` + $m[1], ";
else $q.= "`$key`='".$this->escape($val)."', ";
}

$q = rtrim($q, ', ') . ' WHERE '.$where.';';

return $this->query($q);
}#-#query_update()


#-#############################################
# desc: does an insert query with an array
# param: table (no prefix), assoc array with data
# returns: id of inserted record, false if error
function query_insert($table, $data) {
$q="INSERT INTO `".$this->pre.$table."` ";
$v=''; $n='';

foreach($data as $key=>$val) {
$n.="`$key`, ";
if(strtolower($val)=='null') $v.="NULL, ";
elseif(strtolower($val)=='now()') $v.="NOW(), ";
else $v.= "'".$this->escape($val)."', ";
}

$q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");";

if($this->query($q)){
//$this->free_result();
return mysql_insert_id($this->link_id);
}
else return false;

}#-#query_insert()


#-#############################################
# desc: throw an error message
# param: [optional] any custom error to display
function oops($msg='') {
if($this->link_id>0){
$this->error=mysql_error($this->link_id);
$this->errno=mysql_errno($this->link_id);
}
else{
$this->error=mysql_error();
$this->errno=mysql_errno();
}
?>
<table align="center" border="1" cellspacing="0" style="background:white;color:black;width:80%;">
<tr><th colspan=2>Database Error</th></tr>
<tr><td align="right" valign="top">Message:</td><td><?php echo $msg; ?></td></tr>
<?php if(!empty($this->error)) echo '<tr><td align="right" valign="top" nowrap>MySQL Error:</td><td>'.$this->error.'</td></tr>'; ?>
<tr><td align="right">Date:</td><td><?php echo date("l, F j, Y \a\\t g:i:s A"); ?></td></tr>
<?php if(!empty($_SERVER['REQUEST_URI'])) echo '<tr><td align="right">Script:</td><td><a href="'.$_SERVER['REQUEST_URI'].'">'.$_SERVER['REQUEST_URI'].'</a></td></tr>'; ?>
<?php if(!empty($_SERVER['HTTP_REFERER'])) echo '<tr><td align="right">Referer:</td><td><a href="'.$_SERVER['HTTP_REFERER'].'">'.$_SERVER['HTTP_REFERER'].'</a></td></tr>'; ?>
</table>
<?php
}#-#oops()


}//CLASS Database
###################################################################################################

?>


If it matters, I'm using System.Net.DownloadFileAsync() and using that url that sends out headers and forces a download. Having my doubts that it will happen like that and download the end result not the page source.
  • 0

#2 grisha

grisha

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 106 posts
  • Location:Poland
  • Programming Language:C, C++, C#, PHP, JavaScript

Posted 06 February 2012 - 08:12 AM

Try to remove the PHP end tag from the database.class.php file, and also don't use UTF8 with BOM.
  • 0

#3 Alexander

Alexander

    YOL9

  • Moderator
  • 3963 posts
  • Location:Vancouver, Eh! Cleverness: 200
  • Programming Language:C, C++, PHP, Assembly

Posted 06 February 2012 - 03:02 PM

From visiting the page, there are some errors including
Warning: filesize() [function.filesize]: stat failed for http://tlokzz.info/updater/files/cu_1200.exe in /home/tlokzzi1/public_html/updater/api/download.php on line 30
Warning: readfile(http://tlokzz.info/updater/files/cu_1200.exe) [function.readfile]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in /home/tlokzzi1/public_html/updater/api/download.php on line 33

Those push before headers even if the previous problem were fixed.

At here:
output started at /home/tlokzzi1/public_html/updater/api/database.class.php:[B]264[/B]

There may be a line of which fails at 264 in this file (i.e. failed transaction with your database, closing tag ?>) that causes an issue even before the first header call (not limited to the filesystem errors above).

As Grisha has mentioned it may possibly as well be a byte order mark (0xFFEE in UTF-8, an invisible nonbreaking space) set by your text processor. Most have the option to save in ASCII or without this UTF-8 byte order mark.

Some debugging may prove useful.

Side notes: The file name is usually wrapped around double quotes in the header content-disposition. "SHOULD be" is used however in the related RFCs, and is probably not significant. Your die()'s will always cause headers to fail, you may wish to implement something that does not require output (i.e. turning error display off, logging on, sending users to error page instead of abortion)
  • 0

All new problems require investigation, and so if errors are problems, try to learn as much as you can and report back.


#4 MeekLogic

MeekLogic

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 177 posts
  • Location:Fresno, CA
  • Programming Language:C#, PHP, JavaScript, PL/SQL, Visual Basic .NET, Lua

Posted 06 February 2012 - 03:21 PM

Well since you said that I kinda figured that it might be because I haven't uploaded the file it's looking for yet. So I did it and it didn't change.

I commented out the die in my script but no change. Maybe it's all the outputs that DB class does. I think I'm going to rewrite it. Also the UTF-8 part. Where do you change this?

Oh and I lied above. It did change a bit when adding the file to it's spot. It added a bunch of crazy chars I'm assuming it's trying to read it binary and outputting it in the page.

Starting to feel a little over my head. Need to do a lot of research obviously.

Edit: Little research shows that you guys are talking about the format UTF-8 that the file is stored in on the server. PHP doesn't interpret it so APACHE does and any output screws up header work because it sent out data. Checked around in my IDE, NetBeans, for changing it and can't find anything.

2nd Edit: Removed ?> in DB class and it worked. Weird.
  • 0





Also tagged with one or more of these keywords: runtime, header

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download