COMPUTERWORLD
 

profil kontakt CD-ROM CW100 p°edplatnΘ

archiv anketa CO VY NA TO? CW kariΘra serißly
 

IDG

IDG CZ homepage
COMPUTERWORLD
PC WORLD
INTERNET4U
MEGABYTE
TESTCENTRUM
ON-LINE






COMPUTERWORLD 22/98

P°edßvßnφ parametr∙ pomocφ rozhranφ CGI

Ji°φ Kosek ml.

CGI skripty, kterΘ jsme si ukßzali v poslednφm dφlu naÜeho serißlu, byly velmi jednoduchΘ -- zejmΘna proto, ₧e ke svΘ Φinnosti nepot°ebovaly ₧ßdnΘ informace od u₧ivatele. To vÜak nenφ p°φliÜ typick² p°φklad. Obvykle slou₧φ CGI skripty jako rozhranφ pro prßci s r∙zn²mi databßzemi. U₧ivatel m∙₧e nap°φklad zadat klφΦovß slova, kterß ho zajφmajφ. KlφΦovß slova se p°edajφ CGI skriptu a ten jako sv∙j v²sledek m∙₧e vygenerovat seznam vÜech Φlßnk∙ z databßze, kterΘ obsahujφ zadanß klφΦovß slova.

Z minula ji₧ vφme, ₧e parametry nejprve p°edß prohlφ₧eΦ serveru a ten je pak pomocφ rozhranφ CGI p°edß skriptu. Nejprve se tedy podφvejme na to, jak m∙₧e n∞jakß data poslat prohlφ₧eΦ serveru.

Existujφ 2 metody, jak p°enos dat uskuteΦnit. Prvnφ se jmenuje GET a slou₧φ pro p°enos kratÜφch informacφ. Pro p°enos v∞tÜφho mno₧stvφ dat pak slou₧φ metoda POST.

P°i pou₧itφ metody GET se vÜechny p°edßvanΘ informace p°ipojφ jako dotaz za otaznφk na konec URL, kterΘ ukazuje na CGI skript. V dotazu je pot°eba provΘst drobnΘ ·pravy: vÜechny mezery se nahradφ znakem "+" a znaky se specißlnφm v²znamem se nahradφ sekvencφ znak∙ "%xx", kde xx je hexadecimßlnφ k≤d znaku. Nap°φklad lomφtko se p°evede na sekvenci "%2F".

Pokud tedy chceme skriptu pokus.cgi jako parametr p°edat jmΘno "Jan Novak", m∙₧eme pou₧φt jedno z nßsledujφcφch URL:

http://server/cgi-bin/pokus.cgi?Jan+Novak

http://server/cgi-bin/pokus.cgi?Jan%20Novak

V obou dvou p°φpadech jsme museli p°ek≤dovat mezeru tak, aby URL tvo°ilo jeden dlouh² nep°eruÜen² °et∞zec.

TakovΘto zadßvßnφ parametr∙ vÜak nenφ pro u₧ivatele zrovna pohodlnΘ. NaÜt∞stφ existuje n∞kolik u₧ivatelsky p°φjemn∞jÜφch zp∙sob∙, jak p°im∞t prohlφ₧eΦ k vygenerovßnφ pot°ebnΘho URL s parametry:

- Strßnka obsahuje ve svΘm zßhlavφ tag <ISINDEX>. V tomto p°φpad∞ si prohlφ₧eΦ od u₧ivatele vy₧ßdß zadßnφ textu do vstupnφho pole. Obsah pole zak≤duje podle vÜech pravidel a metodou GET jej odeÜle skriptu urΦenΘmu pomocφ <BASE HREF="URL-skriptu">.

- U obrßzku, kter² je souΦasn∞ odkazem, pou₧ijeme atribut ISMAP. Takto p°ipraven² obrßzek pak slou₧φ jako klikacφ mapa, kterou obsluhuje server. Pokud n∞kam do obrßzku klikneme myÜφ, odeÜlou se metodou GET na server sou°adnice kliknutφ. Na jejich zßklad∞ server obvykle vrßtφ n∞jakou strßnku. Dnes se tento zp∙sob ji₧ p°φliÜ nevyu₧φvß, proto₧e klientskΘ klikacφ mapy jsou mnohem efektivn∞jÜφ. I p°esto malß ukßzka:

<A HREF="http://www.nekde.cz/imagemap">
<IMG SRC="mapa.gif" ISMAP></A>

Pokud u₧ivatel klikne na obrßzek mapa.gif nap°. na sou°adnicφch (x,y)=(10,50), na server se odeÜle po₧adavek http://www.nekde.cz/imagemap?10,50.

- Nejpou₧φvan∞jÜφ metodou je za°azenφ formulß°e (element FORM) na strßnku. U formulß°e musφme specifikovat p°enosovou metodu GET pomocφ atributu METHOD=GET. Formulß° m∙₧e obsahovat vstupnφ pole n∞kolika typ∙. ┌daje zadanΘ do t∞chto vstupnφch polφ se p°ed odeslßnφm zak≤dujφ, p°i°adφ se jmΘnu vstupnφho pole a navzßjem se odd∞lφ znakem "&".

Pokud chceme pro p°edßnφ dat pou₧φt metodu POST, musφme na strßnce op∞t pou₧φt formulß°, ale jako metodu je t°eba uvΘst POST. Data se k≤dujφ stejn²m zp∙sobem jako v metod∞ GET, ale pro jejich odeslßnφ se vytvo°φ zvlßÜtnφ datovΘ spojenφ mezi prohlφ₧eΦem a serverem. To umo₧≥uje p°enßÜet v∞tÜφ objemy dat, ne₧ p°edstavuje p°idßnφ parametr∙ na konec URL.

Zp∙sob zak≤dovßnφ ·daj∙ z formulß°e si p°edvedeme na malΘ ukßzce. P°edpoklßdejme nßÜ znßm² formulß° z p°edchozφch dφl∙:

<FORM ACTION="http://server/cgi-bin/obsluha.cgi" METHOD=GET>
JmΘno: <INPUT TYPE=TEXT NAME=jmeno><BR>
V∞k: <INPUT TYPE=TEXT NAME=vek><BR>
<INPUT TYPE=SUBMIT VALUE="Odeslßnφ formulß°e">
</FORM>

Pokud u₧ivatel vyplnφ jako jmΘno "Pavel Severa" a jako v∞k "47", prohlφ₧eΦ po stisknutφ tlaΦφtka Odeslßnφ formulß°e vygeneruje nßsledujφcφ po₧adavek:

http://server/cgi-bin/obsluha.cgi?jmeno=Pavel+Severa&vek=47

Vidφme, ₧e obsah jednotliv²ch polφ je identifikovßn sv²m jmΘnem a pole jsou odd∞lena znakem "&".

U₧ vφme, jak m∙₧e prohlφ₧eΦ poslat data na server. Vra¥me se tedy k otßzce, jak server p°edß data naÜemu skriptu. Rozhranφ CGI nßm nabφzφ 3 mo₧nosti:

1. Data jsou skriptu p°edßna jako parametry na p°φkazovΘ °ßdce. To p°ichßzφ v ·vahu p°i p°edßvßnφ opravdu krßtkΘ informace pomocφ metody GET (klφΦovß slova zadanß pomocφ <ISINDEX> nebo sou°adnice na klikacφ map∞).

2. Data jsou p°edßna v prom∞nnΘ prost°edφ QUERY_STRING. Tento zp∙sob je typick² pro p°edßvßnφ dat z formulß°e odeslanΘho metodou GET.

3. Data jsou p°edßna na standardnφ vstup skriptu -- zp∙sob typick² pro p°edßnφ dat z formulß°e odeslanΘho metodou POST.

Krom∞ dat od u₧ivatele, kterß p°edß server skriptu, mßme k dispozici dalÜφ u₧iteΦnΘ informace ulo₧enΘ v prom∞nn²ch prost°edφ (viz tabulka 1).

Tab. 1: Prom∞nnΘ prost°edφ p°edßvanΘ skriptu rozhranφm CGI

Prom∞nnßObsah

REQUEST_METHODUrΦuje zp∙sob p°edßvßnφ informacφ -- GET nebo POST

QUERY_STRINGObsahuje data p°enßÜenß metodou GET

PATH_INFOCesta, kterß mß b²t zpracovßna skriptem; nejΦast∞ji jde o Φßst cesty v URL za jmΘnem skriptu

PATH_TRANSLATEDCesta ke stejnΘmu souboru jako PATH_INFO; v tomto p°φpad∞ vÜak byla cesta p°emapovßna podle konfigurace serveru

CONTENT_TYPEMIME typ dat zasφlan²ch metodou POST

CONTENT_LENGTHDΘlka dat zasφlan²ch metodou POST

SCRIPT_NAMEURL prßv∞ provßd∞nΘho skriptu

SERVER_NAMEJmΘno serveru

SERVER_PORT╚φslo portu

SERVER_SOFTWAREJmΘno a verze programu pracujφcφho jako WWW server

SERVER_PROTOCOLJmΘno a verze protokolu, kter²m p°iÜel po₧adavek (typicky HTTP/1.0 nebo HTTP/1.1)

GATEWAY_INTERFACEOznaΦenφ a verze pou₧itΘho rozhranφ ke spuÜt∞nφ skriptu (typicky CGI/1.1)

REMOTE_HOSTDomΘnovß adresa poΦφtaΦe, z n∞ho₧ p°iÜel po₧adavek

REMOTE_ADDRIP adresa poΦφtaΦe, z n∞ho₧ p°iÜel po₧adavek

AUTH_TYPEZp∙sob pou₧itΘ autorizace u₧ivatele

REMOTE_USERV p°φpad∞, ₧e byl u₧ivatel autorizovßn, obsahuje tato prom∞nnß jeho jmΘno

REMOTE_IDENTInformace o identit∞ zφskanß zp∞tn²m dotazem u klienta; tuto vlastnost p°φliÜ mnoho server∙ nevyu₧φvß

Nynφ u₧ toho vφme dost na to, abychom si ukßzali CGI skript, jen₧ bude zpracovßvat parametry zadanΘ u₧ivatelem. Pou₧ijeme nßÜ osv∞dΦen² p°φklad, kter² hodnotφ u₧ivatele podle jeho v∞ku. Zadßnφ ·daj∙ umo₧nφme u₧ivateli v²Üe uveden²m formulß°em. Skript, kter² vyhodnotφ ·daje na formulß°i, pojmenujeme obsluha.cgi.

#!/bin/sh

echo 'Content-type: text/html'

echo

echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">'

echo '<HTML>'

echo '<HEAD>'

echo '<TITLE>Obsluha formulß°e</TITLE>'

echo '</HEAD>'

echo '<BODY>'

echo '<H1>V²sledek obsluhy formulß°e</H1>'

eval `echo $QUERY_STRING | awk 'BEGIN{RS="&"} {printf "WWW_%s\n",$1}' `

WWW_jmeno=`echo $WWW_jmeno | tr "+" "\040"`

echo "$WWW_jmeno je"

if [ $WWW_vek -lt 10 ]; then

echo 'p∞knej mlφΦnßk'

elif [ $WWW_vek -lt 20 ]; then

echo 'teenager'

elif [ $WWW_vek -lt 60 ]; then

echo 'v nejlepÜφch letech'

elif [ $WWW_vek -lt 100 ]; then

echo 'je pravd∞podobn∞ prarodiΦ'

else

echo 'je n∞kde mezi stovkou a smrtφ'

echo '</BODY>'

echo '</HTML>'

CGI skript jsme op∞t zapsali v p°φkazovΘm interpretu sh. P°edem upozor≥uji, ₧e po vyzkouÜenφ skriptu je nejlepÜφ jej ihned smazat. NßÜ skript toti₧ nenφ zdaleka bezpeΦn², jak si za chvφli ukß₧eme.

Podφvejme se nynφ na skript troÜku podrobn∞ji. Prvnφ °ßdek obsahuje urΦenφ interpretu, kter² se na skript pou₧ije. Dßle pak generujeme HTTP hlaviΦku a kostru HTML strßnky.

Dva °ßdky na zaΦßtku t∞la strßnky jsou opravdu magickΘ. Prvnφ z nich pro ka₧dΘ pole formulß°e, jeho₧ hodnota je p°edßna v prom∞nnΘ QUERY_STRING, vytvo°φ prom∞nnou WWW_jmΘno-pole s obsahem p°φsluÜnΘho pole. To nßm usnadnφ dalÜφ prßci s p°edan²mi parametry. Druh² °ßdek v prom∞nnΘ WWW_jmeno (ta nese obsah vstupnφho pole jmeno) nahradφ vÜechny v²skyty znaku "+" mezerou (ASCII k≤d 40 v osmiΦkovΘ soustav∞).

Podmφnka [ $WWW_vek -lt n ] je spln∞na, pokud je prom∞nnß $WWW_vek menÜφ ne₧ n. N∞kolik vno°en²ch podmφnek zajistφ vytiÜt∞nφ p°φsluÜnΘho komentß°e podle v∞ku u₧ivatele.

Vidφme, ₧e tvorba skript∙ cestou p°φkazovΘho interpretu je urΦena spφÜe pro unixovΘho specialistu, ne₧li pro "normßlnφho Φlov∞ka".

BezpeΦnost a CGI skripty

Pro psanφ CGI skript∙ se nejΦast∞ji pou₧φvajφ interpretovanΘ jazyky jako Bourne shell (sh) nebo Perl. To vÜak p°inßÜφ velkß bezpeΦnostnφ rizika. Ukß₧eme si zde bezpeΦnostnφ dφru v naÜem skriptu.

Pokud n∞kdo bude chtφt nßÜ skript zneu₧φt pro zjiÜt∞nφ d∙le₧it²ch informacφ o systΘmu, m∙₧e vyu₧φt n∞kterΘ mΘn∞ znßmΘ vlastnosti interpretu sh. Mezi n∞ pat°φ i to, ₧e na jednΘ °ßdce lze p°φkazy odd∞lovat pomocφ st°ednφku -- to mß v²znam, pokud nap°. n∞jak² "chytrßk" zavolß nßÜ skript pomocφ nßsledujφcφho URL:

http://server/cgi-bin/obsluha.cgi?;who

Nßsledkem tohoto p°φkazu dojde v CGI skriptu k expanzi p°φkazu echo $QUERY_STRING na echo ;who. V²sledkem je, ₧e na v²stup skriptu se zapφÜe prßzdnß °ßdka (p°φkaz echo) a v²sledek programu who. Zcela kdokoliv tak m∙₧e zjistit, kdo v danou chvφli pracuje na serveru. Mφsto p°φkazu who m∙₧eme pou₧φt libovoln² jin² p°φkaz -- nap°. nßsledujφcφ URL:

http://server/cgi-bin/obsluha.cgi?;cat</etc/passwd

Vrßtφ se nßm strßnka, kterß na svΘm zaΦßtku bude obsahovat v²pis informacφ o vÜech u₧ivatelφch systΘmu. Z tohoto v²pisu lze zjistit u₧ivatele, kte°φ heslo nemajφ nastaveno, a u t∞ch ostatnφch lze pom∞rn∞ snadno jejich heslo rozÜifrovat. Kdokoliv se pak pomocφ protokolu Telnet m∙₧e p°ipojit na server a provßd∞t tam tΘm∞° cokoliv.

Pokud tedy chceme vytvß°et bezpeΦnΘ skripty v interpretovan²ch jazycφch, musφme v₧dy p°φchozφ data zkontrolovat a p°ed jejich zpracovßnφm z nich eliminovat vÜechny nebezpeΦnΘ znaky (jako je st°ednφk).

OÜet°it vÜechny nebezpeΦnΘ kombinace vstupnφch parametr∙ nenφ vÜak v∙bec jednoduchΘ a je celkem pravd∞podobnΘ, ₧e na n∞jakou mo₧nost zapomeneme. Je proto lepÜφ CGI skripty psßt v jazycφch, ve kter²ch je nutno program p°ed spuÜt∞nφm p°elo₧it do spustitelnΘ formy. V t∞chto jazycφch (C, C++, Java apod.) je pak v²Üe zmφn∞nΘ nebezpeΦφ obelst∞nφ skriptu do znaΦnΘ mφry eliminovßno.

Vid∞li jsme, ₧e CGI skripty jsou jako ohe≥ -- dobr² sluha, ale Üpatn² pßn. V serißlu se budeme p°φÜt∞ zab²vat p°edevÜφm skriptovacφmi jazyky, kterΘ se vklßdajφ p°φmo do HTML strßnky, jako je PHP a ASP. Prßce s nimi je jednoduÜÜφ a v∞tÜinou i efektivn∞jÜφ. Pro specißlnφ aplikace vÜak m∙₧e b²t v²hodnΘ pou₧φt CGI skripty -- a nynφ ji₧ znßte princip jejich prßce a zp∙sob p°edßvßnφ parametr∙.

V p°φÜtφch pokraΦovßnφch serißlu se podφvßme na r∙znΘ druhy vstupnφch polφ, kterΘ lze pou₧φvat ve webovsk²ch formulß°φch.

 

 

© IDG Czechoslovakia, a.s., VÜechna prßva vyhrazena
info@idg.cz, webmaster@idg.cz