Gzip Sıkıştırma veriyi Hasarlı

2 Cevap php

Bu benim 'gzip.php' bulunan sitemde, içeriği Gzip Sıkıştırma için yazdım yazısıdır. Bunu kullanmak yolu ben Gzip Sıkıştırma etkinleştirmek istediğiniz sayfalarındaki I üst dosyasını içerir ve altta böyle çıktı işlevini çağırmak olduğunu:

print_gzipped_page('javascript')

Dosya Ben $ tip argüman olarak 'css' kullanmak ve bir php dosyası eğer ben herhangi bir bağımsız değişkeni bildirmek olmadan işlevini çağırmak bir css dosyası ise. Script hasarlı veriler nedeniyle sayfayı çözemedi söyleyerek bir hata verir Opera hariç tüm tarayıcılarda çalışıyor. Herkes yanlış yaptım bana söyleyebilir?

<?php
function print_gzipped_page($type = false) {
    if(headers_sent()){
        $encoding = false;
    }
    elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false ){
        $encoding = 'x-gzip';
    }
    elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false ){
        $encoding = 'gzip';
    }
    else{
        $encoding = false;
    }
    if ($type!=false) {
        $type_header_array = array("css" => "Content-Type: text/css", "javascript" => "Content-Type: application/x-javascript");
        $type_header = $type_header_array[$type];
    }

    $contents = ob_get_contents();
    ob_end_clean();
    $etag = '"' .  md5($contents) . '"';
    $etag_header = 'Etag: ' . $etag;
    header($etag_header);

    if ($type!=false) {
        header($type_header);
    }

    if (isset($_SERVER['HTTP_IF_NONE_MATCH']) and $_SERVER['HTTP_IF_NONE_MATCH']==$etag) {
        header("HTTP/1.1 304 Not Modified");
        exit();
    }

    if($encoding){
        header('Content-Encoding: '.$encoding);
        print("\x1f\x8b\x08\x00\x00\x00\x00\x00");
        $size = strlen($contents);
        $contents = gzcompress($contents, 9);
        $contents = substr($contents, 0, $size);
    }

    echo $contents;
    exit();
}

ob_start();
ob_implicit_flush(0);
?>

Ek bilgi: sıkıştırılmış belgenin uzunluğu sadece 10-15 karakter ise komut çalışır.

Yardım için teşekkürler, düzeltilmiş versiyon:

<?php
function print_gzipped_page($type = false) {
    if(headers_sent()){
        $encoding = false;
    }
    elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false ){
        $encoding = 'x-gzip';
    }
    elseif( strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false ){
        $encoding = 'gzip';
    }
    else{
        $encoding = false;
    }
    if ($type!=false) {
        $type_header_array = array("css" => "Content-Type: text/css", "javascript" => "Content-Type: application/x-javascript");
        $type_header = $type_header_array[$type];
        header($type_header);
    }

    $contents = ob_get_contents();
    ob_end_clean();

    $etag = '"' .  md5($contents) . '"';
    $etag_header = 'Etag: ' . $etag;
    header($etag_header);

    if (isset($_SERVER['HTTP_IF_NONE_MATCH']) and $_SERVER['HTTP_IF_NONE_MATCH']==$etag) {
        header("HTTP/1.1 304 Not Modified");
        exit();
    }

    if($encoding){
        header('Content-Encoding: ' . $encoding);
        $contents = gzencode($contents, 9);
    }

    $length = strlen($contents);
    header('Content-Length: ' . $length);
    echo $contents;
    exit();
}

ob_start();
ob_implicit_flush(0);
?>

2 Cevap

İki şey öne çıkmaktadır:

1) Eğer sıkıştırılmış veri boyutuna Content-Length üstbilgisi ayarı gibi görünmüyor. (Belki bunu göz ardı ettik.) Eğer bir tarayıcı çok erken veri gönderme bitirdim düşündüğünüzden bu set yoksa.

2) Eğer sıkıştırılmamış $ boyutu ile sıkıştırılmış $ içeriğin substr yapıyoruz. Bazı tarayıcılar tüm indirilen tampon sıkıştırmasını deneyebilir iç yapısı bir EOF işaretleyici ancak diğer tarayıcılar (Opera?) Sahip olduğunda açılıyor duracaktır. Bu kesinlikle bir 'hasarlı veri' hatası verecekti. Havai miktarı ve sıkıştırma miktarı tam olarak eşleşmesi olabilir çünkü küçük tamponlar ile bu sorunu görüyor olabilir.