Jelen fejezetben azt tekintjük át, hogy milyen http fejléceket kell a CGI programnak magának előállítania, és ezeket hogyan kell a webszerver felé elküldenie.
Alaphelyzetben a CGI programnak nem kell semmilyen fejlécet előállítania. A minimálisan szükséges fejléceket a html szöveg elé odateszi a webszerver, elegendő, ha a CGI program magát a HTML szöveget visszaküldi.
Persze igen gyakran előfordul, gyakorlatilag az iskolapéldák után szinte azonnal az első komolyann CGI alkalmazásnál, hogy a programozó igenis szeretne HTTP fejléceket küldeni a webszerveren keresztül a böngészőnek. A CGI erre is teremt lehetőséget.
Megtehetjük, hogy a teljes általunk küldendő fejlécet
a program a HTML kód előtt kiírja, pontosan úgy, ahogy annak a http
válaszban szerepelnie kell. Ekkor egy program, például a
#!/usr/bin/perl
require 'state.pl';
print_http_state('200 OK');
$time = time();
print <<END;
Content-type: text/html
<HTML>
<BODY>
$time
</BODY>
</HTML>
END
nem csak a HTML sorokat írja ki, hanem a fejléceket is. Persze aki ismeri a HTTP szabványt annak feltűnhet,
hogy az első sor NEM http fejléc, a http szabványban nincs olyan fejlécsor, hogy Status. Valóban
ez egy olyan fejlécsor, amelyet a Webszerver értelmez, és amelyet átalakít a megfelelő
HTTP/1.0 200 OK formára. Az IIS viszont nem viseli el ezt a formát, és
ha WindowsNT alatt futtatunk Perl CGI programokat, akkor a HTTP/1.0 200 OK sort kell
a programnak minden más fejlécsor előtt kiírnia. Ugyanakkor az Apache nem fogadja el, csak a
Status formátumú megadást. Szerencsére azonban még így is lehet protábilis
programokat írni, mert a Webszerverek a megfelelő környezeti változókban
sok mindent elárulnak, nem csak a http kérés fejlécéről, de magukról is.
Létezik a fejlécekkel kapcsolatban az NPH fogalma is, amely a No Parsed Header angol kifejezés rövidítése, amely azt jelenti, hogy a webszerver a CGI alkalmazás által visszaküldött http választ teljesnek tekinti, nem vizsgálja, hogy van-e benne Status vagy bármilyen más olyan fejléc, amellyel kezdeni tud valamit, nem tesz a CGI program által generált fejlácek elé, vagy mögé semmit, hanem leküldi egy az egyben a böngészőknek.
Az nph scriptek írására a CGI szabvány azt mondja, hogy ezek a futtatandó fájlok nph- karakterekkel kell, hogy kezdődjenek.
Térjünk tehát rá arra, hogy milyen fejléceket érdemes a programnak a HTML szöveg előtt küldenie. Nem fogunk minden fejlécet áttekinteni, csak a legfontosabbakat.
Content-type
A legfontosabb, és a Status után az első amit minden programnak küldenie kell,
az a Content-type fejlécsor, amelyben a böngészővel közöljük, hogy a küldendő
információ, amelyik a fejlécsorok után jön, milyen MIME típusú. Ez általában text/html de
ha nem HTML szöveget küldünk vissza, csak sima szöveget akkor text/plain, de előfordulhat,
hogy egy bináris állományt küldünk vissza, ami mondjuk egy GIF kép, akkor image/gif az
érték, így a programsor, amelyik ezt az információs mint fejlécsort kinyomtatja:
print "Content-type: text/html\n";
vagy
print "Content-type: text/plain\n";
vagy
print "Content-type: image/gif\n";
vagy valami más a visszadott tartalomnak megfelelően. Itt kellmegjegyezni, bár nem egészen ide
tartozik, hogy Perl nyelvben mindenképpen ajánlatos a binmode használata amikor valamilyen
nem ASCII fájl olvasunk vagy írunk. Igaz ugyan, hogy UNIX alatt ez teljesen felesleges, de még
egy UNIX-ra írt CGI program is elkerülhet esetleg egyszer egy WindowsNT gépre. Akár Apache
Webszerverrel együtt. Így a következő példaprogram CGI scripten keresztül küld a felhasználónak
egy GIF képet, amelyen egy kislány látható (a kép nem túl élvezetes, nem azért van):
#!/usr/bin/perl
require 'state.pl';
print_http_state('200 OK');
print <<END;
Content-type: image/gif
END
open(F,"girl.gif");
binmode F;
binmode STDOUT;
while( read(F,$buffer,1024) ){
print $buffer;
}
close F;
Location
Ez egy olyan fejléc, amellyel azt mondhatjuk aböngészőnek, hogy az információ, amit ő kér nem
is ott van, ahol ő keresi, hanem valahol máshol. Ilyenkor általában a Status sorban sem
a 200 OK üzenetet adja vissza a program, hanem valamilyen más hibakódot, általában a
301 Moved Permanently értéket. Ez azt jelenti a böngészőnek, hogy a kért információ
nem ott található, ahol ő keresi, hanem valahol máshol, nevezetesen a Location fejlécsorban
megadott helyen. Egy egyszerű példaként álljon itt egy kis script, amelyik a felhasználót
az AltaVizsla keresőhöz küldi:
#!/usr/bin/perl
require 'state.pl';
print_http_state('301 Permanently Moved');
print <<END;
Location: http://altavizsla.matav.hu
END
Mire jó ez? Nos a leggyakrabban a hirdetési bannereket megjelenítő programok
használják ezt a technikát. Amikor megjelenik egy hirdetési kép, és valaki rákattint,
akkor nem lehet azonnal a hirdető Web oldalaira küldeni, mert előtte a hirdetést megjelenítő
szolgáltató még rögzíteni akarja egy naplófájlba, hogy egy rákattintás történt, és csak ezután
küldi el a felhasználót a keresett oldalra. Például az Internetto
is ezt a technikát használja.
Ha valaki Apache webszervert használ, és valamilyen oknál fogva egy weboldalba a képeket CGI scripten keresztül akarja küldeni, például azért, mert ellenőrizni akarja, hogy aki le akarja tölteni az oldalt az kifzette-e a havi díjat és így jogosult a képek megnézésére, akkor is használhatja ezt a technikát. Sokkal hatékonyabb lesz, mint beolvasni az egész fájlt, majd a CGI processzen keresztül elküldeni a webszervernek, amelyik azt továbbküldi. Az Apache van annyira intelligens, hogy észreveszi, hogy a cgi script az elérendő információ helyeként egy olyan URL-t adott meg, amelyet szintén ő kezel, és ahelyett, hogy a hibakódot leküldené a böngészőnek, rögtön az új URL-en levő információt küldi le. Ami persze lehet kép, szöveg, hang vagy akár egy újabb CGI script, vagy valamilyen más információ, amelyet például egy Apache modul kezel. Ha pedig nem fizetett, akkor a visszatérési státusz kód lehet 402.
Content-Length
Ebben a fejléc mezőben adhatjuk meg, hogy milyen hosszú a visszaküldött HTML oldal, vagy egyéb
információ. Ha ezt nem teszzük meg, akkor ezt vagy megteszi helyettünk a webszerver vagy nem. Ennek
ellenőrzésére kiváló kis program a proxy.pl program. Mindenesetre
ha megtesszük, akkor sokkal nagyobb biztonságban érezhetjük magunkat afelől, hogy a böngésző
rendben megejelníti a leküldött információt. Ha nincs megadva a tartalom hossza, akkor a böngésző
nem lehet egészen biztos abban, hogy az egész tartalmat megkapta-e. Ha viszont megadjuk, akkor
a böngésző azt figyelembe veszi, és például az előző példát módosítva:
#!/usr/bin/perl
require 'state.pl';
print_http_state('200 OK');
print <<END;
Content-type: image/gif
Content-Length: 1200
END
open(F,"girl.gif");
binmode F;
binmode STDOUT;
while( read(F,$buffer,1024) ){
print $buffer;
}
close F;
IE4.0 böngészőben a képnek csak egy része jelenik meg, pedig az egész képet leküldi a
cgi processz.