IFrame Comet response contains no data - php

I'm experimenting with Comet and I'm stuck with implementing it via a hidden IFrame ("forever frame".
This is my index.html:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
cometResponse = function() {
var debugOut = document.getElementById('debugOutput');
return function(response) {
debugOut.innerHTML = response.number;
}
}
</script>
</head>
<body>
<div id="debugOutput"></div>
<iframe src="comet.php"></iframe>
</body>
</html>
And this is the comet.php file:
<?php
set_time_limit(0);
header('Content-Type: text/html');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Transfer-Encoding: chunked');
flush();
ob_flush();
$response = '<script type="text/javascript">
parent.cometResponse({
number: %1$d
});
</script>';
for ($i = 0; $i < 2; $i++) {
sleep(1);
$data = sprintf($response, $i);
$output = strtoupper(dechex(strlen($data)))."\r\n".$data."\r\n";
echo $output;
flush();
ob_flush();
}
echo "0\r\n\r\n";
After loading the page, the browser seems to "wait" for the response. After a few seconds, Firebug shows an empty response with these response headers:
HTTP/1.1 200 OK
Date: Mon, 26 Jul 2010 09:34:04 GMT
Server: Apache/2.2.14 (Win32) PHP/5.2.12
X-Powered-By: PHP/5.2.12
Cache-Control: no-cache, must-revalidate
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html;charset=ISO-8859-2
Since the response is treated as empty, the tag that should be in the response doesn't get executed either.
However, if I remove the "Transfer-Encoding: chunked" header, the content is sent to the browser correctly but all in one big piece at the end of the script, as expected.
I just can't find what's going wrong here.

Two guesses:
Content-Encoding: gzip
Maybe mod_gzip does not work correctly?
Have you tried on annother host?
Maybe Firefox ignores the code, if
it is not within < html>

This might help someone else, here is how I solved it:
<?php
header('Content-Encoding: chunked');
header('Transfer-Encoding: chunked');
header('Content-Type: text/html');
header('Connection: keep-alive');
header('Cache-Control: no-cache, must-revalidate');
flush();
set_time_limit(0);
function chunk($data) {
echo sprintf("%x\r\n%s\r\n", strlen($data), $data);
flush();
ob_flush();
}
// Code to output data here.
// The following loop is an example.
for($i = 0; $i < 5; $i++) {
chunk('<script type="text/javascript">window.top.test();</script>');
sleep(1);
}
chunk('');
?>
It needed an empty chunk at the end of the output.
Then you can simply output data by calling the function chunk like this:
chunk('data');

Related

PHP echos file as text instead of binary on server

I have written a PHP page which reads a file and does echo it after adding some headers:
header('Content-disposition: filename="' . $fname . '"');
header('Pragma: no-cache');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-type: $AttachFileType");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($ffullname));
echo file_get_contents($ffullname);
This piece of code does well on local test, but when porting to the server, the response is not as expected. For example when I want to retrieve a png file, I get the below image on local test:
while server test outputs this one:
As I have investigated, the only difference of them is 4 additional headers on server response. Local test response headers:
Cache-Control: must-revalidate, post-check=0, pre-check=0
Connection: Keep-Alive
Content-disposition: filename="attachment_hrmstotal_generalskills_6.png"
Content-Length: 2401
Content-Transfer-Encoding: binary
Content-Type: png
Date: Wed, 23 May 2018 04:45:02 GMT
Expires: 0
Keep-Alive: timeout=5, max=97
Pragma: public
Server: Apache/2.4.27 (Ubuntu)
and server response headers are these:
Cache-Control: must-revalidate, post-check=0, pre-check=0
Connection: keep-alive
Content-disposition: filename="attachment_hrmstotal_generalskills_1.png"
Content-Length: 184450
Content-Transfer-Encoding: binary
Content-Type: png
Date: Wed, 23 May 2018 04:40:56 GMT
Expires: 0
Pragma: public
Server: nginx/1.8.0
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
The last four headers is the difference. What is the problem, its reason and how to solve it?
Your content-type should be Content-type: image/png

header("Content-Disposition: attachment) not working

I have tried to export the mysql data result to excel. After click the Export button, the form will send parameter's value into doexport.php.
The result was appeared in console.
<?php
session_start(); //Start the session
include('install_lang_japanese.php');
//connect to database
$dbc=mysqli_connect(_SRV,_ACCID,_PWD,"QPL");
if(!$dbc){
die('Connect Error: ' . mysqli_connect_error());
}
if(isset($_POST['action'])){
switch($_POST['action']){
case 'senddatacar':
$start = mysqli_real_escape_string($dbc,$_POST['startdate']);
$end = mysqli_real_escape_string($dbc,$_POST['enddate']);
$sqlex = "SELECT * FROM table";
$result =mysqli_query($dbc,$sqlex) or die(_ERROR30.":".mysqli_error($dbc));
$filename="cardata".date('ymd').".xls";
header("Content-type: application/vnd.ms-excel; name='excel'");
header(sprintf("Content-Disposition: attachment; filename=$filename"));
header("Pragma: no-cache");
header("Expires: 0");
//Then echo table
break;
}
mysqli_close($dbc);
}
My problem is : i don't see any file has downloaded as excel
Response Header at console :
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Disposition:attachment; filename=cardata170929.xls
Content-Length:2988
Content-Type:application/vnd.ms-excel; name='excel'
Date:Fri, 29 Sep 2017 05:02:19 GMT
Expires:0
Pragma:no-cache
Server:Apache/2.2.22 (Ubuntu)

Content-length is capped to 2 GB

I've created a script that lets the user download files:
function file_size($filename)
{
exec('stat -c %s ' . escapeshellarg($filename), $return);
return (float)$return[0];
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filename));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . file_size($filename));
readfile($filename);
exit;
Very simple. The file_size function lets me detect file sizes larger than 2 GB.
The problem is that Content-length never is above 2 GB:
< HTTP/1.1 200 OK
< Date: Sun, 21 Aug 2011 09:33:20 GMT
< Server: Apache
< Content-Description: File Transfer
< Content-Disposition: attachment; filename=very-large-file
< Content-Transfer-Encoding: binary
< Expires: 0
< Cache-Control: must-revalidate, post-check=0, pre-check=0
< Pragma: public
< Content-Length: 2147483647
< Content-Type: application/octet-stream
Doing a var_dump on 'Content-Length: ' . file_size($filename) returns string(26) "Content-Length: 4689218232". If I access the file directly without a PHP script, there is no problem and Apache is reporting the correct file size:
< HTTP/1.1 200 OK
< Date: Sun, 21 Aug 2011 09:58:33 GMT
< Server: Apache
< Last-Modified: Thu, 06 Jan 2011 21:56:47 GMT
< ETag: "8ba8f5e0-1177fcab8-49934940b30e5"
< Accept-Ranges: bytes
< Content-Length: 4689218232
But I'd really like to serve the file through my PHP script. Thank you for your time.
Sending huge files with readfile is not good practice.
Use X-Sendfile, like this: header("X-Sendfile: $filename");. You'll need apache mod_sendfile. This should also solve your file-size problem.

create javascript code in a php file - SAFARI/CHROME doesn't work

I've created a .php file that write out js code like that:
<?
//my_js.php
// javascript header
header('Content-type: text/javascript');
// Date in the past
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
// always modified
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
// HTTP/1.1
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
?>
//
// js code here
//
then i include the script above in my index.php file like this:
<script type="text/javascript" src="my_js.php?id=<? echo $id ?>">
</script>
This works perfect in Firefox, but SAFARI and CHROME doesn't include my_js.php file at all!
What i'm doing wrong?
**edit:
this is the rendered html in index.php:
<script type="text/javascript" src="my_js.php?id=new"></script>
and this is the my_js.php code:
(it's a very big file so i write out only the first few lines)
var g = { sitepath: "myNullUrl" }
function getBrowserWidth(){
if (window.innerWidth){
return window.innerWidth;}
else if (document.documentElement && document.documentElement.clientWidth != 0){
return document.documentElement.clientWidth; }
else if (document.body){return document.body.clientWidth;}
return 0;
}
that's a strange problem 'cos while i'm viewing source code from Crome/Safari i can access the js file and it seems to be error free!
I'm using Chrome 6.04 and Safari 5, both for mac.
It may be because it is expecting the file-extension to be my_js.js. If this is the case, save your PHP file as my_js.js, then, assuming you're using Apache, use the Apache Directive: ForceType:
Like so:
<Location /your/path/my_js.js>
ForceType application/x-httpd-php
</Location>
Good luck!
Maybe set Content-Disposition: inline; header?
<?php
if(strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false) {
header("Content-type: text/javascript");
header("Content-Disposition: inline; filename=\"download.js\"");
header("Content-Length: ".filesize("my-file.js"));
} else {
header("Content-type: application/force-download");
header("Content-Disposition: attachment; filename=\"download.js\"");
header("Content-Length: ".filesize("my-file.js"));
}
header("Expires: Fri, 01 Jan 2010 05:00:00 GMT");
if(strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false) {
header("Cache-Control: no-cache");
header("Pragma: no-cache");
}
include("my-file.js
");
?>
It should work. Or you can change this:
header('Content-type: text/javascript');
to this
header('Content-type: application/javascript');
Note:
application/javascript: JavaScript; Defined in RFC 4329 but not accepted in IE 8 or earlier
text/javascript is allowed in HTML 4 and 5 and, unlike application/javascript, has cross-browser support

Changing CRC of a file through readfile()

I have this code set up that lets a user download a file through my server from a URL they specify. The file streams through using readfile() so it only uses my bandwidth.
<?php
set_time_limit(0);
$urlParts = explode("/", $_SERVER['PHP_SELF']);
$file = $urlParts[3];
header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . $file);
header("Content-Transfer-Encoding: binary\n");
readfile($file);
?>
This script works, but it does not change the CRC hash of the downloaded file. What I want it to do is append some random bits to the end of the file so it can change the hash without corrupting it. I have tried adding something like echo md5(rand() . time()); to the end of the script but it doesn't work.
If this is possible with something like cURL I'd appreciate if someone could put up some code samples, because i'd switch to cURL if this was possible.
Thanks for your help.
Hmm, your code works for me:
test.php:
set_time_limit(0);
$urlParts = explode("/", $_SERVER['PHP_SELF']);
//$file = $urlParts[3];
$file = 'toread.txt';
header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . $file);
header("Content-Transfer-Encoding: binary\n");
readfile($file);
echo md5(rand() . time());
?>
toread.txt:
This is the content of toread.txt
Now using curl, I get the following results:
>curl -i http://example.com/test.php
HTTP/1.1 200 OK
Date: Tue, 04 Mar 2014 07:09:39 GMT
Server: Apache
Cache-Control: public, must-revalidate
Pragma: hack
Content-Disposition: attachment; filename=toread.txt
Content-Transfer-Encoding: binary
Transfer-Encoding: chunked
Content-Type: application/force-download
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Age: 0
This is the content of toread.txt38d8a8009fad7315bdf5e823a06018e7
And the second one:
>curl -i http://example.com/test.php
HTTP/1.1 200 OK
Date: Tue, 04 Mar 2014 07:09:57 GMT
Server: Apache
Cache-Control: public, must-revalidate
Pragma: hack
Content-Disposition: attachment; filename=toread.txt
Content-Transfer-Encoding: binary
Transfer-Encoding: chunked
Content-Type: application/force-download
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Age: 0
This is the content of toread.txt3b87356ea9ee007b70cfd619e31da950

Categories