Version: 1.1

Type: Function

Category: HTTP

License: GNU General Public License

Description: Dynamic pages normally doesn't hand cache expires and modification very nicely. Also web caches and browsers have problems with dynamic contents. I provide a function that is called with the last modification date of the data base/dynamic content. It complies with HTTP/1.1 (RFC2616) and HTTP/1.0 strong and wek validators. It also takes in account, and differentiates that the same page might beaccesed anonymously or user authenticated. The original version was implemented in bulma.lug.net, which uses PHP4 and Postgres7



// Autor: gallir@uib.es, header implementation for weak y strong
// HTTP validator according to RFC2616 of HTTP/1.1
// It's also compatible with HTTP/1.0 and 
// take care of Netscape non-standard headers
// If more than 10800 secs have gone since last load
// it makes the client/cache to reload the page

// Call this function before doing anything else with databases or similar.

function DoHeaders($lastModified, $logged=FALSE) {
   // $lastModified: last database modification, in "epochs"
   //$logged: FALSE/TRUE // It takes in account that pages can be accessed
	 					// as public or authorised
	 
	$now = time();
	$maxCache = $now - 10800; // Max. time before refreshing
	$headers = getallheaders();
	$refresh=TRUE; // refresh, as default

	if(isset($headers["If-Modified-Since"])) { 
		// NetCrap sends ";lenght = xxx" after the date
		$arraySince = explode(";", $headers["If-Modified-Since"]);
		$since = strtotime($arraySince[0]);
		if($since >= $lastModified) $refresh=FALSE;
	}

	if($logged) {
		$tag="\"AUT".$lastModified."\"";  // A private page
	} else {
		$tag="\"PUB".$lastModified."\"";  // and public one
	}

	if(isset($headers["If-None-Match"])) { // check ETag
		if(strcmp($headers["If-None-Match"], $tag) == 0 )
			$refresh=FALSE;
		else 
           $refresh=TRUE;
	}
	if(!$refresh) {
		header("HTTP/1.1 304 Not changed");
		// The first header must be this
		// otherwise Netcrap gives "No Data" error
		$strLastModified = gmdate("r", $lastModified);
	} else
		$strLastModified = gmdate("r", $now);

	header("ETag: $tag");  // The new TAG
	header("Last-Modified: $strLastModified");
	header("Expires: " . gmdate("r", time()+1));
	header("Cache-Control: max-age=1, must-revalidate"); // HTTP/1.1
	// Netscape doesn't handle very well the header("Pragma: no-cache");
	if(!$refresh) {
		ob_end_clean(); // Just in case..
		die; // Don't do anything more
	}
	ob_start(); // We start buffering to allow "Content-Lenght" header
				// at the end of the output to allow HTTP/1.0 persistent connections.
}


// Add following code at the end of your output

// If we allowed buffering before, we send the lenght
// to allow HTTP/1.0 persistent connections
function SendLength() {
	if(ob_get_length()) {
		header("Content-Length: " . ob_get_length());
		ob_end_flush();
		die;  // Delete it if you don't want to finish the script
	}
}