304 Not Modified header not working within a class

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi list, my first message here :)

To the point: I'm programming a class that takes several CSS files, parses,
compresses and saves into a cache file. However, I would like to go a step
further and also use the browser cache, handling the 304 and 200 header
types myself.

Now, what is the problem? If I do it within a function, there is absolutely
no problem, everything works like a charm. However, when I implement that
same concept into my class, there is no way I can send a 304 Not Modified
header, when the data is *over* ~100 bytes.

What is funnier is that it enters the 304 function within the class, but
apparently it doesn't respect that and ends sending a 200 OK header anyway.
Let's take a look at the code:

This is a simple test scenario implemented within a little file just to
proof and make sure it is working before I adapt the code in the class.
Everything is ok here:

define('TIME_BROWSER_CACHE','3600');
$last_modified = filemtime('blabla.css');

if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) AND
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified) {
  header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified',TRUE,304);
  header('Pragma: public');
  header('Last-Modified: '.gmdate('D, d M Y H:i:s',$last_modified).' GMT');
  header('Cache-Control: max-age='.TIME_BROWSER_CACHE.', must-revalidate,
public');
  header('Expires: '.gmdate('D, d M Y H:i:s',time() + TIME_BROWSER_CACHE).'
GMT');
  die();
}
header('Content-type: text/css; charset=UTF-8');
header('Pragma: public');
header('Last-Modified: '.gmdate('D, d M Y H:i:s',$last_modified).' GMT');
header('Cache-Control: max-age='.TIME_BROWSER_CACHE.', must-revalidate,
public');
header('Expires: '.gmdate('D, d M Y H:i:s',time() + TIME_BROWSER_CACHE).'
GMT');

Now the class (simplified):

  public function printme($method = 'file') {
    if($this->qCSS > 0 AND ($method == 'file' OR $method = 'inline')) {
      if ($method == 'file') {
        $last_modified = filemtime(CACHE_LOCATION);
        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) AND
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified AND
$this->valid_cache()) {
          // $this->valid_cache() determines if the internal CSS cache is
still valid. If it is, it returns TRUE, else FALSE
          header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified', TRUE,
304);
          // also tried sending header('HTTP/1.1 304 Not Modified'); but
that didn't do the trick
          header('Pragma: public'); // Useless? Maybe, but the function
works with or without it.
          header('Last-Modified: '.gmdate('D, d M Y H:i:s',$last_modified).'
GMT'); // Always good to send this too.
          header('Cache-Control: max-age='.TIME_BROWSER_CACHE); // idem
          header('Expires: '.gmdate('D, d M Y H:i:s',time() +
TIME_BROWSER_CACHE).' GMT'); // idem
          $fp = fopen('cache/hi.txt','a'); // Just to check stuff
          fwrite($fp,'header 304 sended, let\'s die'."\n"); // It logs this
without problem, which means it really enters this function when needed.
          fclose($fp);
          die(); // Terminate script execution or else it would continue to
the bottom, which isn't necessary.
        }
        header('Content-type: text/css; charset='.CHARSET); // From here on,
it applies only if we need to send the CSS.
        if (USE_BROWSER_CACHE) { // Constant [TRUE|FALSE] which defines
whether to use the browser cache or not.
          header('Pragma: public');
          header('Last-Modified: '.gmdate('D, d M Y H:i:s',$last_modified).'
GMT');
          header('Cache-Control: max-age='.TIME_BROWSER_CACHE);
          header('Expires: '.gmdate('D, d M Y H:i:s',time() +
TIME_BROWSER_CACHE).' GMT');
        }
        // Rest of the function: get the CSS and echo it, within an
ob_start('ob_gzhandler');
        (....)
        $content_length = filesize(CACHE_LOCATION);
        if (extension_loaded('zlib')) $content_length = ob_get_length();
        header('Content-Length: '.$content_length); // Necesary if we don't
want to send the CSS in chunks.
        if (extension_loaded('zlib')) ob_end_flush();

Other useful information:
- Code #1 returns an 304 when it is needed, even when the CSS size is over
50kb. (Haven't test any CSS over that size yet)
- Code #2 goes into the 304 part but doesn't send the 304, unless the total
CSS size is under 100 bytes.
- Tried also with ETags, didn't worked either.
- Tried increasing or decreasing TIME_BROWSER_CACHE, didn't worked.
- Tried with/without Pragma header, Last-Modified header, Cache-Control
header, Expires header, all the 16 posibilities. None of them worked.
- Tried with getallheaders() and making the proper changes.
- Tried with/without ob_gzhandler.
- Tried with/without ob_start().
- Tried with all options on/off within Last-Modified header and
Cache-Control header (must-revalidate, public, etc). None of them worked.
- Tried searching on Google, reading the comments on php.net and searching
within this list. Nothing like this came up.
- I've been checking everything with Live HTTP Headers, a plugin for
Firefox. Haven't tested it on other browsers yet. However, I don't think
this is a browser issue.
- I've been using PHP 5.2.6 with Suhosin, APC and xDebug installed.
Webserver is Apache 2.2.8. Everything is working fine there. Proof is
everything goes well within the first code.

Any suggestions? What am I doing wrong?

Greetings and thanks in advance :)
If you need to take a look at more code, just ask for it, and sorry for my
bad english, it's not my native language.

-- 
Mailed by:
UnReAl4U - unreal4u
ICQ #: 54472056
www1: http://www.chw.net/
www2: http://unreal4u.com/

[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux