-
1. Data: 2009-09-04 16:12:58
Temat: Problem wyświetlania grafiki generowanej dynamicznie
Od: "Marek" <m...@s...interia.pl>
Witam,
Mam pewien problem związany z wyświetlaniem przez przegladarki rysunków
generowanych w PHP. Zabrakło pewnie jakiegoś nagłówka lub jest ich za dużo.
Sam już nie wiem. Otóż gdy robię link do statycznego pliku graficznego na
serwerze to otwiera mi się on w przeglądarce. Gdy natomiast link prowadzi do
jakiegoś skryptu PHP wysyłającego do przeglądarki ten sam rysunek, to
przeglądarka próbuje zapisać go jako plik zamiast wyświetlić. W dodatku tego
typu pliki nie są cache'owane. Co zrobić aby przeglądarka traktowała rysunek
tworzony dynamicznie jak każdy inny (czyli wyświetlała go i cacheowała)?
Obecnie wysyłam nagłówki w postaci:
header("Accept-Ranges: bytes");
header("Content-Length: ".$fileInfo["file_size"]);
header("Content-Type: ".$fileInfo["file_mime"]);
header("Content-Disposition: attachment;
filename=\"".$fileInfo["file_name"]."\"");
Próbowałem zabaw z mod_rewrite lecz bezskutecznie. Próbowałem rysunek
dynamiczny w postaci rysunek.php?id=1234 zamaskować tak aby dostęp do niego
był np. nieistniejacy_katalog/rysunek_1234.jpg. Plik uparcie chce się
zapisać a nie otwiera się w oknie przeglądarki.
--
Pozdrawiam,
Marek
-
2. Data: 2009-09-04 17:21:51
Temat: Re: Problem wyświetlania grafiki generowanej dynamicznie
Od: "Marek" <m...@s...interia.pl>
Przepraszam - już znalazłem odpowiedź :-) Należało obsłużyć nagłówek Etag i
wszystko działa :-)
--
Pozdrawiam,
Marek
-
3. Data: 2009-09-04 17:52:56
Temat: Re: Problem wyświetlania grafiki generowanej dynamicznie
Od: porneL <n...@p...net>
On Fri, 04 Sep 2009 17:12:58 +0100, Marek <m...@s...interia.pl>
wrote:
> header("Accept-Ranges: bytes");
Obsługujesz Ranges? (PHP nie zrobi tego za ciebie)
> header("Content-Length: ".$fileInfo["file_size"]);
> header("Content-Type: ".$fileInfo["file_mime"]);
> header("Content-Disposition: attachment;
> filename=\"".$fileInfo["file_name"]."\"");
Attachment oznacza, że nie należy tego wyświetlać na stronie, tylko
zapisać na dysk.
Poza tym nie escape'ujesz file_name. Jeśli to zawiera dane z zewnątrz, to
uważaj, żeby ci ktoś response splitting attack nie zaserwował.
> Próbowałem zabaw z mod_rewrite lecz bezskutecznie. Próbowałem rysunek
> dynamiczny w postaci rysunek.php?id=1234 zamaskować tak aby dostęp do
> niego był np. nieistniejacy_katalog/rysunek_1234.jpg. Plik uparcie chce
> się zapisać a nie otwiera się w oknie przeglądarki.
mod_rewrite jest lepsze od nie-do-końca-standardowego Content-Disposition.
--
http://pornel.net
this.author = new Geek("porneL");
-
4. Data: 2009-09-04 20:19:42
Temat: Re: Problem wyświetlania grafiki generowanej dynamicznie
Od: "Marek" <m...@s...interia.pl>
>> header("Accept-Ranges: bytes");
> Obsługujesz Ranges? (PHP nie zrobi tego za ciebie)
W zasadzie jeszcze nie - eksperymentuję póki co.
> Attachment oznacza, że nie należy tego wyświetlać na stronie, tylko
> zapisać na dysk.
Tak, ale tylko przy wiadomościach email. Przy obrazkach WWW teoretycznie
nagłówek nie powinien w ogóle być stosowanym. Do dyspozycji mam tylko inline
jeszcze, co niczego nie zmienia w zachowaniu browsera. Nagłówek nieformalnie
służy do wymuszenia nazwy pliku gdy jego URL nie wskazuje na plik o
docelowej nazwie. Przeglądarki to obsługują w taki sposób, że zapisze Ci się
plik pod właściwą nazwą ...ale ... w konsekwencji bezpośrednie wejście na
dany URL (zamiast ze znacznika <img>) spowoduje, że przeglądarka będzie
chciała zapisać ten plik zamiast go otworzyć. No i to właśnie jest źródłem
moich problemów.
Chyba wpadłem na rozwiązanie. Na serwerze zastosuję mod_rewrite tak aby
zamiast obrazek.php?id=1234 pisać obrazki_1234/nazwa.jpg. Czyli tak jakby
każdy z obrazków był w innym katalogu. Wtedy nazwa jest zachowana oraz ID
przemycony oraz mogę pominąć Content-Disposition. No i będzie można bez
problemu otwierać URLe w przeglądarce.
> Poza tym nie escape'ujesz file_name. Jeśli to zawiera dane z zewnątrz, to
> uważaj, żeby ci ktoś response splitting attack nie zaserwował.
Hmmm... masz rację. Wszystkie nazwy pochodzą z CMS i są korygowane do ASCII
w chwili ładowania grafiki w sekcji redakcyjnej. Czy powinienem zastosować
urlencode() do nazwy?
Sprawę cacheowania też rozwiązałem. Nagłówek Etag do tego służy. Jednakże
pod FF dzieją się cuda. Jeśli obrazki są wczytywane przez Flasha a nie
bezpośrednio przez FF, to tylko niewielka ich część podda się cacheowaniu.
Przy kolejnych odświeżeniach coraz więcej zaczyna być zcache'owanych.
Jednakże nigdy nie bądą wszystkie i co ciekawe - nie poddadzą się temu
zawsze te same obrazki. FF nie wysyła dla nich nigdy do serwera nagłówka
If-None-Match.
-
5. Data: 2009-09-04 20:39:56
Temat: Re: Problem wyświetlania grafiki generowanej dynamicznie
Od: porneL <n...@p...net>
On Fri, 04 Sep 2009 21:19:42 +0100, Marek <m...@s...interia.pl>
wrote:
>>> header("Accept-Ranges: bytes");
>> Obsługujesz Ranges? (PHP nie zrobi tego za ciebie)
>
> W zasadzie jeszcze nie - eksperymentuję póki co.
Jak jeszcze nie, to jeszcze nie wysyłaj tego nagłówka :)
>
>> Attachment oznacza, że nie należy tego wyświetlać na stronie, tylko
>> zapisać na dysk.
>
> Tak, ale tylko przy wiadomościach email. Przy obrazkach WWW teoretycznie
> nagłówek nie powinien w ogóle być stosowanym.
Ale go stosujesz :)
> Do dyspozycji mam tylko inline jeszcze, co niczego nie zmienia w
> zachowaniu browsera.
Powinno (w tych, co słuchają się attachment). Może Content-Type masz zły?
> Hmmm... masz rację. Wszystkie nazwy pochodzą z CMS i są korygowane do
> ASCII w chwili ładowania grafiki w sekcji redakcyjnej. Czy powinienem
> zastosować urlencode() do nazwy?
Niestety każda przeglądarka to rozumie inaczej, a oficjalny standard jest
niewyobrażalnie udziwniony. Najlepiej ograniczyć nazwy do ASCII i usuwać
wszystkie podejrzane znaki z nazwy (przynajmniej \n i ").
> Sprawę cacheowania też rozwiązałem. Nagłówek Etag do tego służy.
Dorzuć Expires i/lub Cache-Control: max-age=<dużo>.
--
http://pornel.net
this.author = new Geek("porneL");
-
6. Data: 2009-09-04 21:14:52
Temat: Re: Problem wyświetlania grafiki generowanej dynamicznie
Od: "Marek" <m...@s...interia.pl>
> Jak jeszcze nie, to jeszcze nie wysyłaj tego nagłówka :)
Dobra, przepraszam, więcej nie będę :-))))
> Ale go stosujesz :)
jak nizej :-)
> Powinno (w tych, co słuchają się attachment). Może Content-Type masz zły?
Być może powinno. Sprawdziłem na FF. Kompletnie nie ma żadnej różnicy.
Content-Type jest wyłącznie obrazkowy. JPG, GIF, PNG, czasem Flash.
Testowałem akurat na JPGach.
> Niestety każda przeglądarka to rozumie inaczej, a oficjalny standard jest
> niewyobrażalnie udziwniony. Najlepiej ograniczyć nazwy do ASCII i usuwać
> wszystkie podejrzane znaki z nazwy (przynajmniej \n i ").
No i tak właśnie robię. Pod IE nazwy z polskimi literami powodowały, że plik
graficzny zapisywał się pod nazwą *.bmp - z tego co pamiętam.
> Dorzuć Expires i/lub Cache-Control: max-age=<dużo>.
Ok, sprawdzę jutro jak to się zachowa. Aczkolwiek już teraz jest dobrze z
wyjątkiem czytania plików przez Flasha. Może to coś zmieni... zobaczymy.