How to determine the Content-Length of a gzipped file?

前端 未结 3 1789
半阙折子戏
半阙折子戏 2020-12-10 12:35

Right now I\'m trying to serve CSS and JS files from a server that won\'t let me enable mod_gzip or mod_deflate. So I wrote a small PHP script to

相关标签:
3条回答
  • 2020-12-10 13:05

    You need to first do the entire gzip and measure the result (either holding the contents in memory, or writing them to disk as you compress and then stat'ing the gzipped file), then write the Content-Length header and then send the file contents.

    Or use chunked transfer encoding.

    0 讨论(0)
  • 2020-12-10 13:07

    To solve your firefox issue, I think you need to include header( "Content-Encoding: gzip" ); so that the browser knows to decompress the content.

    As for the content length, you can try just leaving this value off, or try to figure out a way to use "Transfer-Encoding: chunked" (you can't jsut send this header, you need to format the data specially for it). It is possible that ob_end_flush automatically enables chunking.

    I recommend you get wireshark and capture what your php script is sending and compare it to a properly behaving server to see what headers, etc are missing.

    0 讨论(0)
  • 2020-12-10 13:12

    The problem here is that to know the content length you need to know whether or not the client supports gzip encoding and you've delegated that decision by using ob_gzhandler. From HTTP Headers:

    ob_start();
    ob_start('ob_gzhandler');
    
      ... output the page content...
    
    ob_end_flush();  // The ob_gzhandler one
    
    header('Content-Length: '.ob_get_length());
    
    ob_end_flush();  // The main one
    

    Complete version:

    $filename = "style.css";
    
    if (!file_exists($filename) || !($info = stat($filename))) {
      header("HTTP/1.1 404 Not Found");
      die();
    }
    
    header("Date: ".gmdate("D, j M Y H:i:s e", time()));
    header("Cache-Control: max-age=2592000");
    header("Last-Modified: ".gmdate("D, j M Y H:i:s e", $info['mtime']));
    header("ETag: ".sprintf("\"%x-%x-%x\"", $info['ino'], $info['size'], $info['mtime']));
    header("Accept-Ranges: bytes");
    header("Expires: ".gmdate("D, j M Y H:i:s e", $info['mtime']+2592000));
    header("Content-Type: text/css"); // note: this was text/html for some reason?
    
    ob_start();
    ob_start("ob_gzhandler");
    echo file_get_contents($filename);
    ob_end_flush();
    header('Content-Length: '.ob_get_length());
    ob_end_flush();
    

    This is much better than taking on the gzip encoding issue yourself.

    0 讨论(0)
提交回复
热议问题