title: Handling If-modified-since header in a PHP-script
body: <p>I have a PHP script which is called with an <strong>?img=</strong> parameter.</p>
  
  <p>The value for that parameter is an (urlencoded) URL of an image.</p>
  
  <p>My script checks, if that image is already stored at my server.</p>
  
  <p>If not - it downloads it. After that it optionally resizes the image and sends it to STDOUT, i.e. back to the requesting browser, prepended with <strong>Content-Type</strong> and <strong>Last-modified</strong> headers:</p>
  
  <pre><code>Connection:close
  Content-Type:image/jpeg
  Date:Fri, 01 Jun 2012 08:28:30 GMT
  Last-Modified:Fri, 01 Jun 2012 08:02:44 GMT
  Server:Apache/2.2.15 (CentOS)
  Transfer-Encoding:chunked
  X-Powered-By:PHP/5.3.3
  </code></pre>
  
  <p>This is needed to workaround some crossdomain issues and works well for me since over a year:</p>
  
  <p><a href="https://i.stack.imgur.com/9msZR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9msZR.png" alt="screenshot"></a></p>
  
  <p>However I'd like to add functionality to handle the incoming <strong>If-Modified-since</strong> header - to send a <strong>Not Modified 304</strong> response.</p>
  
  <p>My questions are:</p>
  
  <p>1) Is that even possible in PHP, when run in Apache?</p>
  
  <p>2) How to handle (i.e. parse and produce) the dates best in PHP here?</p>
  
  <p>Bonus question) How to add a <strong>Content-Length</strong> header for the resized images?</p>
  
  <p>My code is below (I've omitted the CURL-downloading part):</p>
  
  <pre><code>&lt;?php
  
  define('CACHE_DIR', '/var/www/cached_avatars/');
  
  $img    = urldecode($_GET['img']);
  $cached = CACHE_DIR . md5($img);
  
  # omitted downloading part for brevity
  
  $readfh = fopen($cached, 'rb');
  if ($readfh) {
          flock($readfh, LOCK_SH);
  
          $size = getimagesize($cached);
          $w    = $size[0];
          $h    = $size[1];
          $type = $size[2];
          $mime = $size['mime'];
  
          # find the downscale factor to fit image into $maxw x $maxh
          $scale = max($w / $maxw, $h / $maxh);
  
          header('Content-Type: ' . $size['mime']);
          header('Last-Modified: ' . gmdate('D, d M Y H:i:s T', filemtime($cached)));
  
          $length = filesize($cached);
          $buf = fread($readfh, $length);
          fclose($readfh);
  
          # the image is smaller than $maxw x $maxh, do not scale up
          if ($scale &lt;= 1) {
                  header('Content-Length: ' . $length);
                  print($buf);
                  return;
          }
  
          $tw = $w / $scale;
          $th = $h / $scale;
          $image = imagecreatefromstring($buf);
          $thumb = imagecreatetruecolor($tw, $th);
          imagecopyresampled($thumb, $image, 0, 0, 0, 0, $tw, $th, $w, $h);
          imagedestroy($image);
  
          # How to add Content-Length here, after image resizing?
  
          if (IMAGETYPE_JPEG == $type)
                  imagejpeg($thumb, null, 75);
          else if (IMAGETYPE_PNG == $type)
                  imagepng($thumb, null, 9);
          else if (IMAGETYPE_GIF == $type)
                  imagegif($thumb, null);
  
          imagedestroy($thumb);
  }
  
  ?&gt;
  </code></pre>