-
1. Data: 2009-09-30 00:35:01
Temat: Problem z nagłówkami HTTP 1.1
Od: "Marek" <m...@s...interia.pl>
Witam,
Mam problem z określeniem wartości przekazywanej w nagłówku Content-Length.
Otóż skrypt PHP wysyła zawartość pliku w następujący sposób:
header('HTTP/1.1 200 OK');
header("Etag: \"".$fileInfo["Etag"]."\"");
header("Content-Type: ".$fileInfo["file_mime"]);
header("Last-Modified: ".$fileInfo["Date"]." GMT");
header("Content-Length: ".(strlen($fileInfo["file_data"])+20));
print($fileInfo["file_data"]);
Plik SWF odebrany przez przeglądarkę jest o 20 bajtów krótszy niż zwraca
strlen($fileInfo["file_data"]). Gdy jest nim SWF, to dzieją się wtedy cuda z
tą animacją. Po przekazaniu do nagłówka Content-Length długości pliku
powiększonej o 20, wszystko działa poprawnie, plik przechodzi w całości. W
przypadku gdy do czynienia mamy ze zwykłymi obrazkami, to nie muszę dodawać
tych 20 bajtów, a raczej nie mogę nawet, gdyż wtedy z nimi zaczynają być
problemy. Przeglądarka wtedy czeka na brakujące 20 bajtów, które nigdy nie
nadejdą.
Zmodyfikowałem więc procedurę liczenia długości w następujący sposób:
$length=strlen($fileInfo["file_data"]));
if ($fileInfo["file_mime"]=="application/x-shockwave-fl
ash") $length+=20;
header("Content-Length: ".$length);
Czy ktoś z Was wie skąd to 20 bajtów?
-
2. Data: 2009-09-30 01:08:49
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: porneL <n...@p...net>
On Wed, 30 Sep 2009 01:35:01 +0100, Marek <m...@s...interia.pl>
wrote:
> Zmodyfikowałem więc procedurę liczenia długości w następujący sposób:
>
> $length=strlen($fileInfo["file_data"]));
> if ($fileInfo["file_mime"]=="application/x-shockwave-fl
ash")
> $length+=20;
> header("Content-Length: ".$length);
>
>
> Czy ktoś z Was wie skąd to 20 bajtów?
Może masz włączone mbstring.func_overload? Jeśli tak, to strlen() będzie
podawało bezużyteczną informację.
Nie musisz podawać Content-Length. Jak go nie podasz, to PHP użyje chunked
transfer encoding.
--
http://pornel.net
this.author = new Geek("porneL");
-
3. Data: 2009-09-30 13:01:10
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: "Marek" <m...@s...interia.pl>
> Może masz włączone mbstring.func_overload? Jeśli tak, to strlen() będzie
> podawało bezużyteczną informację.
>
> Nie musisz podawać Content-Length. Jak go nie podasz, to PHP użyje chunked
> transfer encoding.
>
W międzyczasie problem rozwiązał się,
Jest to efekt włączonej kompresji wyjścia dla plików .php, z jakiegoś powodu
niektóre przeglądarki (np. FF 3.x oraz IE8) nie potrafią ściągnąć całego
takiego pliku. Nie ma natomiast problemu z programów typu wget, które mimo
że ściągają w taki sam sposób to jednak plik jest poprawny, rozwiązaniem
jest wyłączenie kompresji wyjścia dla plików SWF na poziomie skryptu lub w
htaccess dla całości konta.
A co do podawania Content-Length to raczej jest konieczność używania z uwagi
na cache'owanie plików przez przeglądarkę. Bez pola daty i /lub długości
obserwowałem za pomocą Firebuga, że pliki są marnie cache'owane. Z każdym
odświeżeniem było co raz więcej cache'owanych. Niektóre z nich nie poddawały
się temu w ogóle. Przeglądarka usuwała Etag wysyłając zapytanie do serwera.
Po uzupełnieniu nagłówków wszystkie pliki ładnie się cache'ują przy
pierwszym wejściu.
-
4. Data: 2009-10-02 00:05:00
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: porneL <n...@p...net>
On Wed, 30 Sep 2009 14:01:10 +0100, Marek <m...@s...interia.pl>
wrote:
> Jest to efekt włączonej kompresji wyjścia dla plików .php, z jakiegoś
> powodu niektóre przeglądarki (np. FF 3.x oraz IE8) nie potrafią ściągnąć
> całego takiego pliku.
Content-Length jest wielkością *po* kompresji.
> Nie ma natomiast problemu z programów typu wget, które mimo że ściągają
> w taki sam sposób to jednak plik jest poprawny, rozwiązaniem jest
> wyłączenie kompresji wyjścia dla plików SWF na poziomie skryptu lub w
> htaccess dla całości konta.
Zapewne nie wysyła Accept-Encoding:gzip
> A co do podawania Content-Length to raczej jest konieczność używania z
> uwagi na cache'owanie plików przez przeglądarkę.
AFAIR wg RFC nie ma takiej konieczności.
> Bez pola daty i /lub długości obserwowałem za pomocą Firebuga, że pliki
> są marnie cache'owane.
Dorzuć Last-Modified, Cache-Control: max-age= albo Expires, obsługuj 304.
Poczytaj RFC 2616.
--
http://pornel.net
this.author = new Geek("porneL");
-
5. Data: 2009-10-02 19:29:31
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: "Marek" <m...@s...interia.pl>
> Content-Length jest wielkością *po* kompresji.
Po kompresji? :-0
To mi szczęka opadła. Czy to oznacza, że albo stosujemy w PHP
zlib.output_compression=ON albo nagłówek Content-Length ?
Nie da się przewidzieć jakiej wielkości będzie plik po kompresji. W końcu
najpierw posługujemy się header() a na końcu robimy print() i sam print
kompresuje dane. Tak więc nie wiem ile danych opuści printa, a już w
szczególności nie będę tego wiedział w chcwili gdy nagłówek wysyłam (czyli
przed użyciuem printa).
Ponadto zauważyłem, że chyba tak nie do końca jest jak napisałeś, albo źle
interpretuję obserwacje. Otóż gdy nawet o 1 bajt źle wpiszę długość
wiadomości to efekty tego doskonale widać w Fierbugu. Dzieją się cuda.
GdyC-L jest za duży to przeglądarka długo wyczekuje reszty pliku, a gdt C-L
jest za krótki - pliki graficzne są uszkodzone i nie wyświetlają się
poprawnie. Tymczasem gdy ustawiam C-L na wartość przed kompresją, to
wszystko działa ok. Może PHP modyfikuje ten nagłówek w tle?
> Zapewne nie wysyła Accept-Encoding:gzip
Tak, o to chodzi. Stąd diagnoza o tym, że FF oraz IE nie radzą sobie z tym w
przypadku SWFów albo PHP uzależnia wielkość transmiscji od nagłówka C-L...
>> A co do podawania Content-Length to raczej jest konieczność używania z
>> uwagi na cache'owanie plików przez przeglądarkę.
>
> AFAIR wg RFC nie ma takiej konieczności.
Wprost nie piszą ale "Applications SHOULD use this field to indicate the
transfer-length of the message-body" a w domyśle (jako konsekwencja moich
obserwacji) "bo w przeciwnym razie przeglądarki nie będą keszowały
poprawnie".
> Dorzuć Last-Modified, Cache-Control: max-age= albo Expires, obsługuj 304.
> Poczytaj RFC 2616.
Oczywiście bez wysyłania 304 nie pisałbym o cache'owaniu przecież :-) W/w
nagłówki niczego nie dawały. Sęk w tym, że brak cacheowania polega na tym,
że przeglądarka zaprzestaje wysyłania do serwera nagłówków, które pozwalają
określić czy należy wysłać 304 czy 200. A tak się dzieje gdy wcześniej
wysłany plik do przeglądarki jest ogołocony z nagłówka C-L i/lub Date. Wtedy
np. Etag wysłany wraz z obrazkiem nie wraca do serwera przy odświeżaniu
strony albo raz jest wysyłany a w przypadku innego pliku - nie jest. Jakaś
losowość następuje - to również przyuważyłem.
-
6. Data: 2009-10-03 10:06:26
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: Paweł Piskorz <n...@p...nie?>
Marek wrote:
>> Content-Length jest wielkością *po* kompresji.
>
> Po kompresji? :-0
> To mi szczęka opadła. Czy to oznacza, że albo stosujemy w PHP
> zlib.output_compression=ON albo nagłówek Content-Length ?
>
> Nie da się przewidzieć jakiej wielkości będzie plik po kompresji.
ob_start();
ob_get_length();
-
7. Data: 2009-10-03 18:01:45
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: porneL <n...@p...net>
On Fri, 02 Oct 2009 20:29:31 +0100, Marek <m...@s...interia.pl>
wrote:
>> Content-Length jest wielkością *po* kompresji.
>
> Po kompresji? :-0
Tak, bo to nie jest informacja o wielkości pliku. To jest informacja dla
klienta HTTP ile bajtów ma pobrać z sieci zanim zobaczy kolejne nagłówki
HTTP albo zamknie połączenie.
> To mi szczęka opadła. Czy to oznacza, że albo stosujemy w PHP
> zlib.output_compression=ON albo nagłówek Content-Length ?
Najlepiej to zostawić w spokoju. HTTP/1.1 radzi sobie bez Content-Length.
> poprawnie. Tymczasem gdy ustawiam C-L na wartość przed kompresją, to
> wszystko działa ok. Może PHP modyfikuje ten nagłówek w tle?
Może - nie sprawdzałem. Możliwe też, że przeglądarki mają jakieś
mechanizmy do radzenia sobie z nieprawidłowym Content-Length.
> Wprost nie piszą ale "Applications SHOULD use this field to indicate the
> transfer-length of the message-body" a w domyśle (jako konsekwencja
> moich obserwacji) "bo w przeciwnym razie przeglądarki nie będą keszowały
> poprawnie".
Bo w przeciwnym wypadku będzie trzeba użyć Transfer-encoding:chunked,
które nieco wydłuża dane i nie jest rozumiane przez klientów HTTP/1.0.
Nie widzę związku z cache. Jak klient potrafi ściągnąć plik, to potrafi go
cache'ować. Jeśli to na prawdę wpływa na cache'owalność plików, to są już
jakieś fanaberie przeglądarek :/
--
http://pornel.net
this.author = new Geek("porneL");
-
8. Data: 2009-10-04 12:40:11
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: "Marek" <m...@s...interia.pl>
> ob_start();
> ob_get_length();
Ahhh... fakycznie mógłbym to zastosować nie tylko przy generowaniu kodu
strony ale i obrazków do niej :) Gapiostwo :-)
Dzięki.
-
9. Data: 2009-10-04 12:49:52
Temat: Re: Problem z nagłówkami HTTP 1.1
Od: "Marek" <m...@s...interia.pl>
> Może - nie sprawdzałem. Możliwe też, że przeglądarki mają jakieś
> mechanizmy do radzenia sobie z nieprawidłowym Content-Length.
Wybadam to. Tylko zastanawia mnie fakt, że gdy dodałem lub odjąłem jeden
bajt, to działy się cuda. Stąd wysnułem wniosek (może mylny), że wysyłam
content-length poprawnie.
> Bo w przeciwnym wypadku będzie trzeba użyć Transfer-encoding:chunked,
> które nieco wydłuża dane i nie jest rozumiane przez klientów HTTP/1.0.
... a w przypadku HTTP/1.1 stwarza problemy z cacheowaniem :-) (dodaję
uparcie)
> Nie widzę związku z cache.
Ja również nie... Empirycznie to stwierdziłem w FF. Nigdzie tego nie
wyczytałem.
> Jak klient potrafi ściągnąć plik, to potrafi go
> cache'ować. Jeśli to na prawdę wpływa na cache'owalność plików, to są już
> jakieś fanaberie przeglądarek :/
Pewnie jest tak jak piszesz. Muszę więc jakoś radzić sobie. Mam serwis o
dużej odwiedzalności i zżerało mi transfer jak cholera. Musiałem więc
przyglądać się każdemu bajtowi 5x zanim go wysłałem. No i stąd moje
doświadczenia. Życie...