Saya akan sangat menghargai bantuan memahami perilaku Apache ini.
Saya berkomunikasi dengan PHP dari aplikasi iPhone Objective-C di application / json. Kompresi Gzip diaktifkan di server, dan diminta oleh klien.
Dari .htaccess saya:
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php application/json
Untuk permintaan kecil, Apache sedang mengatur header 'Content-Length'. Misalnya (nilai-nilai ini adalah output dalam Objective-C dari header):
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Length" = 185; <-------------
"Content-Type" = "application/json";
Date = "Wed, 22 Sep 2010 12:20:27 GMT";
"Keep-Alive" = "timeout=3, max=149";
Server = Apache;
Vary = "Accept-Encoding";
"X-Powered-By" = "PHP/5.2.13";
"X-Uncompressed-Content-Length" = 217;
X-Uncompressed-Content-Length adalah header yang saya tambahkan set ke ukuran string JSON yang tidak terkompresi.
Seperti yang Anda lihat, permintaan ini sangat kecil (217 byte).
Inilah tajuk dari permintaan yang lebih besar (282.888 bytes):
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Type" = "application/json";
Date = "Wed, 22 Sep 2010 12:20:29 GMT";
"Keep-Alive" = "timeout=3, max=148";
Server = Apache;
"Transfer-Encoding" = Identity;
Vary = "Accept-Encoding";
"X-Powered-By" = "PHP/5.2.13";
"X-Uncompressed-Content-Length" = 282888;
Perhatikan bahwa Panjang Konten tidak diberikan.
Pertanyaan saya:
- Mengapa Apache tidak mengirim Panjang Konten untuk permintaan yang lebih besar?
- Apakah fakta bahwa 'Contend-Encoding = gzip' diatur berarti kompresi gzip masih bekerja pada permintaan yang lebih besar, walaupun saya tidak dapat memverifikasi perbedaan ukuran?
- Apakah ada cara saya bisa membuat Apache menyertakan Panjang Konten aktual untuk permintaan yang lebih besar ini agar lebih akurat melaporkan penggunaan data kepada pengguna?
Aplikasi ini dapat digunakan pada paket data yang mahal, karenanya keinginan saya untuk melaporkan penggunaan aktual kepada pengguna, bukan 30-70% penggunaan yang meningkat (beberapa ratus KB tambahan mungkin kedengarannya tidak banyak - tetapi paket ini dapat menelan biaya antara $ 1 dan $ 10 per MB!).
Terima kasih sebelumnya.
sumber
Kedengarannya seperti Apache melakukan pengkodean chunked, ini berarti ia dapat mengirim data karena sedang di-gzip alih-alih menunggu respons penuh untuk di-gzip. Ini praktik yang cukup standar, saya tidak cukup akrab dengan Apache untuk mengatakan apakah itu dapat dinonaktifkan.
sumber
OK, saya berhasil menyelesaikan ini. Seperti yang ditunjukkan Martin F dengan benar, Apache memotong jawaban sehingga ukuran konten tidak diketahui. Bagi banyak orang ini diinginkan (halaman memuat lebih cepat). Ini harus dibayar dengan tidak dapat melaporkan kemajuan pengunduhan.
Bagi mereka seperti saya yang benar-benar ingin melaporkan kemajuan pengunduhan, jika Anda menggunakan dukungan gzip otomatis dari Apache atau PHP, ada sedikit yang bisa Anda lakukan. Solusinya adalah melakukannya secara manual. Lebih mudah daripada kedengarannya:
Jika Anda mengirim seluruh file, maka ini adalah contoh yang bagus dalam PHP untuk memaksa satu potongan (dengan Content-Length): http://www.php.net/manual/en/function.ob-start.php # 94741
Jika Anda mengirim data yang dihasilkan, gunakan gzencode untuk menyandikan data Anda, seperti dalam contoh di atas. Prasyarat adalah bahwa semua data output Anda disimpan dalam variabel (Anda dapat menggunakan ob_start untuk membantu ini jika Anda perlu buffer, lalu dapatkan konten buffer).
Dan voila!
Manfaat besar lainnya dari melakukannya sendiri adalah Anda dapat mengatur level kompresi. Ini bagus untuk aplikasi seluler saya, karena saya dapat mengatur ke tingkat kompresi tertinggi (sehingga pengguna saya membayar lebih sedikit untuk data!) - sedangkan server mungkin hanya menggunakan tingkat kompresi sedang untuk pertukaran ukuran CPU / ukuran yang lebih baik. Level kompresi adalah sesuatu yang saya percaya Anda hanya dapat berubah jika Anda dapat mengedit httpd.conf (yang pada hosting bersama, saya tidak bisa).
Jadi saya telah menyimpan direktif DEFLATE .htaccess saya untuk semuanya kecuali aplikasi / json saya yang sekarang saya encode dengan cara di atas.
Terima kasih lagi Martin F, Anda memberi saya percikan yang saya butuhkan untuk menyelesaikan ini :)
sumber
strlen($replyBody)
sajamb_strlen($replyBody, 'latin1')
. Panjang konten hanyalah jumlah byte (bukan karakter), yang memberikan Anda strlen (). Menggunakan mb_strlen () dengan semacam 'latin1' bekerja karena karakter latin1 selalu 8 bit, tetapi mungkin memiliki masalah dengan pengkodean yang menghasilkan byte yang bukan karakter latin1 yang valid.