#32414 [Opn->Fbk]: session_start(): Cannot send session cache limiter

From: Date: Tue, 22 Mar 2005 17:34:26 +0000
Subject: #32414 [Opn->Fbk]: session_start(): Cannot send session cache limiter
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-77049@lists.php.net to get a copy of this message
 ID:               32414
 Updated by:       sniper@php.net
 Reported By:      d dot geels at grape dot ru
-Status:           Open
+Status:           Feedback
 Bug Type:         Session related
 Operating System: any
 PHP Version:      4.3.10, also 5
 New Comment:

Do you have 'session.auto_start' set on somewhere?
(httpd.conf, .htaccess file, php.ini..) 


Previous Comments:
------------------------------------------------------------------------

[2005-03-22 18:25:12] d dot geels at grape dot ru

There is one more detail, I forgot to mention:
I couldn't kill warning message by calling @start_session() in line 45.
Is this because of warning message issued somewhere in calls from
session_start()?

------------------------------------------------------------------------

[2005-03-22 18:16:04] d dot geels at grape dot ru

Just viewd latest session.c from CVS repository. There are not much
changes between versions 4 and 5, so bug still remains in PHP 5.

Somewhere here:
static int php_session_cache_limiter(TSRMLS_D)
{
	php_session_cache_limiter_t *lim;

// for some reason, this string fails
	if (PS(cache_limiter)[0] == '\0') return 0;
// I cant understand all this file, but I think, problem is
// that value 'none' is not properly recognized or processed

	
	if (SG(headers_sent)) {
		char *output_start_filename =
php_get_output_start_filename(TSRMLS_C);
		int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);

		if (output_start_filename) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session
cache limiter - headers already sent (output started at %s:%d)",
				output_start_filename, output_start_lineno);
		} else {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session
cache limiter - headers already sent");
		}	
		return -2;
	}
	
	for (lim = php_session_cache_limiters; lim->name; lim++) {
		if (!strcasecmp(lim->name, PS(cache_limiter))) {
			lim->func(TSRMLS_C);
			return 0;
		}
	}

	return -1;
}

------------------------------------------------------------------------

[2005-03-22 17:38:57] d dot geels at grape dot ru

Description:
------------
The problem described already in user contributed noted in
documentation. Strange, that it is not yet fixed...
Also problem mentioned in http://bugs.php.net/bug.php?id=11213
==================================
laacz at laacz dot lv (28-Oct-2004 03:37)

If You are not using cookies to store session_id's, that does not mean,
that session_start() will not send any headers at all. It still sends
cache controlling information to user. For example:
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0,
pre-check=0
Pragma: no-cache
Even, if You set cache_limiter to none (via
ini_set('session.use_cookies', 0) or ini_set('session.cache_limiter',
'none')), session_start() still tries to send empty headers and that
causes error message "Cannot send session cache limiter - headers
already sent". So, use output buffering, if You need to output
something before session_start(). 
==================================
even session_cache_limiter('none') doesn't work

In my case, problem is that I call session_start(), then
session_write_close() in the beginning, then send data, then call
session_start(), then session_write_close() in the function, registered
on shutdown.
There are two reasons, why I do so:
1) there are several processes, that access same session (I use
md5($_SERVER['REMOTE_ADDR']) as session_id)
2) I can't buffer output at all. Amount of data is very large, it is a
file being downloaded. It must be sent ASAP.

Reproduce code:
---------------
if(!empty($_SERVER['HTTP_RANGE'])){
	$sid = md5($_SERVER['REMOTE_ADDR']);
	ini_set('session.use_cookies', 0);
	session_cache_limiter('public'); // for IE "Open" bug
	session_id($sid);
	session_start(); //this one starts normally
	//check, if this download thread is permitted or not
	if(!empty($_SESSION['file_'.$file_id]) && $_SESSION['file_'.$file_id]
>= MAX_DOWNLOAD_THREADS){
		header('HTTP/1.1 403 Forbidden', true, 403);
		exit;
	}elseif(!isset($_SESSION['file_'.$file_id]))
$_SESSION['file_'.$file_id] = 0;
	$_SESSION['file_'.$file_id]++;
	session_write_close();
	//close session ASAP, because else other processes would be blocked

	//this function will decrement threads counter...
	function decrementCounter($sid, $file_id)
	{
//this must help us evade "Warning:  session_start(): Cannot send
session cache limiter - headers already sent"
		session_cache_limiter('none');

		session_id($sid);
		session_start(); // this is line #45
		//decrement threads counter
		$_SESSION['file_'.$file_id]--;
		session_write_close();
		//close session ASAP
	}

	//... when script finished
	register_shutdown_function('decrementCounter', $sid, $file_id);
}

Expected result:
----------------
No warnings in log file.

Actual result:
--------------
[Tue Mar 22 18:32:08 2005] [error] PHP Warning:  session_start():
Cannot send session cache limiter - headers already sent (output
started at /home/httpd/pantech/htdocs/file.php:144) in
/home/httpd/pantech/htdocs/file.php on line 45

reproduced always, when user downloading a file

line 144 sends data to client:
echo fread( $fp, $size > READ_BLOCK_SIZE ? READ_BLOCK_SIZE : $size );



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=32414&edit=1


Thread (4 messages)

« previous php.bugs (#77049) next »