0

localhost development server :

Server : Apache/2.4.46 (Unix) OpenSSL/1.1.1j PHP/8.0.3 mod_perl/2.0.11 Perl/v5.32.1

I'm sending etag & last modified response headers with php :

  "Connection    : close"
  "Content-Type  : text/html; charset=UTF-8"
  "Date          : ".gmdate("D, d M Y H:i:s")." GMT";
  "Last-Modified : ".$lastmod;
  "Etag          : ".$etag;
  "Expires       : 1" //can't have the browser doesn't check if file was modified on server
  "Pragma        : public"
  "Cache-Control : max-age=1,must-revalidate"

ob_start("ob_gzhandler") sends

 "Content-Encoding : gzip"

Apache sends :

 "Connection        : Keep-Alive"
 "Keep-Alive        : timeout=5, max=99"
 "Server            : Apache/2.4.46 (Unix) OpenSSL/1.1.1j PHP/8.0.3 mod_perl/2.0.11 Perl/v5.32.1"
 "Transfer-Encoding : chunked"
 "Vary              : Accept-Encoding"
 "X-Powered-By      : PHP/8.0.3"

When the client requests again the same page, I catch with php the if none match & if modified since request headers & can send a 304 not modified response.

if (
((isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
  &&  $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $lastmod )
|| 
(!isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
&& isset($_SERVER['HTTP_IF_NONE_MATCH'])
&& trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag)
)
)
{

   header("HTTP/1.1 304 Not Modified");
   header("Content-Length:0");
   header('Etag:'. $etag);
   header('Last-Modified:'.$lastmod);

   exit;

 } 

However on a subsequent request of the same page, the client doesn't send the if none match and if modified since request headers, and the page is reloaded.

As pointed out in this blog post http://edn.embarcadero.com/article/38123 (however about asp) I also send the same etag & not modified headers with the 304 (+ a content-length : 0 response header).

But it doesn't help, still no if modified since in third request

What can I do to tell the client to always, rather than just one time, send the if none match and/or if modify since request headers ?

mikakun
  • 111
  • 5

1 Answers1

0

I've found out, finally !

The headers need to be exactly the same & sent in the exact same order as the first time the file was sent and possibly before content-length & response code (maybe that is less strict than that but I've spent enough time on this and I'm not going to investigate any more)

Therefore in my case I had to send :

            header("Connection:close");
            header("Date:".gmdate('D, d M Y H:i:s')." GMT");
            header('Last-Modified:'.$lastmod);
            header('Etag:'. $etag);
            header("Expires:".gmdate('D, d M Y H:i:s',parent::$requesttime+self::$expire));
            header("Pragma:public");
            header("Cache-Control:max-age=".self::$expire.",  must-revalidate");
            header("Content-Length:0");
            header("HTTP/1.1 304 Not Modified");

& bingo at last... no more unnecessary 200 !

Hopefully this will help somebody one day.

mikakun
  • 111
  • 5