CGI - Common Gateway Interface
 
teejuht
 
1.
Sissejuhatus
2.
CGI kaudu info saatmine serverist browserisse 
3.
Info browserist serverisse saamine
4.
Apache serveri konfiguratisoon
5.
SSI-Server Side Includes
6.
Forms
7.
Pildi (jpg või gif) browserisse saatmine
8.
Interaktiivne kaart 
 
1. Sissejuhatus

Lühendiga CGI tähistatakse võimalust:

- saata serverist browserisse HTML formaadis infot ning
- saata browserist mingit pidi kodeeritud infot serverisse (server tavaliselt ka saadab browserile midagi tagasi a la "Tänan").

Tavaliselt seisneb kodeering selles, et tühikud on asendatud plussmärkidega ja täpitähed, komad, jms. on esitatud vastavate ASCII koodidena.

CGI on väga erutav teema sellepärast, et võimaldab teha interneti lehekülgi interaktiivsemateks. Nimetagem, et peale CGI on interaktiivsuseks veel olemas JavaSript ja Java. Nagu märgitud saab CGI hakkama kahes suunas info liigutamisega. Oluline on märkida, et serveris võib ka toimuda info töötlus.

Esmalt loetleme millised võimalused on CGI-ga interaktiivsuseks:

- counter ehk lugeja mis loeb teatud kodulehekülje külastamise arvu
- külalisteraamat kuhu saab lehe külastaja teha sissekande mis on pärast kõigile nähtav
- igasugused ankeedi või testi moodi täidetavad lüngad mille täitmisjärgne sisu fikseeritakse
- failide nö. uploadimine (serverisse kopeerimine)
- otsingumootorid

Muud mis ei ole tavaliselt CGI-d:

- jututoad ei ole CGI vaid mitme arvuti väjavalitud porte kuulavate ja sinna kirjutavate protsesside suhtlemine
- animeeritud gif-id
- java applet'id (suhteliselt kvaliteetsed graafilised Netscape'i aknas toimuvad liikumised)

Toodud kirjeldus pole küll sisuline aga peaks mingit selgust looma.

2. CGI kaudu info saatmine serverist browserisse

See on vaieldamatult tähelepanuväärne võimalus, kuigi browserit vaadates ei saa aru kas veeti kohale tavaline html fail või kasutati nö. CGI-d.

Antud juhul tähendab CGI kasutamine seda, et browser ei küsi serverist mitte html faili vaatamiseks vaid browser käivitab serveris programmi mille väljud läheb läbi CGI browserisse. Kõik siin toodud programmid on kirjutatud perlis.

Nt. sisestades Netscape Location reale:

www.tkg.tartu.ee/~imre/tell_me.pl

peaks Netscape pöörduma serveri poole ja seal käivitma programmi

/home/imre/public_html/tell_me.pl

See programm võib olla mis tahes programm (kas perli või shell script või hoopis C binary). Mina olen püüdnub järgida sellist joont, et

shelli script lõpeb .sh
perli script lõpeb .pl
C binary lõpeb .b

Maailmas on levinud veel muid kokkuleppeid, nt. vaatamata sisule kirjutatake nn. CGI scripti lõppu .cgi.  Ja olgu ka üteldud, et tell_me.pl 'i nimetatakse antud olukorras CGI scriptiks või CGI programmiks.

Konkreetsel juhul on ta sellise sisuga,

tell_me.pl:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
$i = 0;
while ($i < 10)
{
print "Hõissa $i. korda<BR>";
$i=$i+1;
}

Ja talle tuleb anda piisavad õigused:

bash# chmod 755 tell_me.pl

Toome veel mõned näited, et huvitavam oleks. Siin eeldadakse, et perl on selge. Kui mitte, siis tutvuge!
 

3. Info browserist serverisse saamine
 
 

See on juba praktilisem asi mis avab tee igasuguste täidetavate vormide tegemiseks (külaliste raamatud, müük internetis ..)

a) info saatmine käsurea argumendina

Sisestame sellise Location read Netscapesse:

www.tkg.tartu.ee/~imre/yks_argument.pl?ahoi

kusjuures /home/imre/public_html/yks_argument.pl on selline:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "$ARGV[0]";

ning anda kõigile sellele failile käivitamise ja lugemisõigus:

bash# chmod 755 yks_argument.pl

Tulemusena peaks browserisse tekkima sõna 'ahoi'.

Selgituseks ütleb niipalju, et perli programmi seisukohalt käivitati ta ühe käsurea argumendiga.
Aga keskkonnamuutujate juurde tuleme hiljem tagasi ja vaatame mis nendega saab head ära teha.
 

b) info saatmine programmi sisendisse

See on natuke keerulisem ja öeldakse, et kasutatakse POST meetodit.

Sisestage Netscape Location reale:

www.tkg.tartu.ee/~imre/arvutaja.html

ja käituge nagu loomulik oleks :)
 

Vaja on .html ja .pl faili mis töötavad kooskõlastatult:

/home/imre/public_html/arvutaja.html
 

<HTML>
<BODY>
tere, siin saab kahte arvu korrutada:<BR>

<FORM METHOD="POST" ACTION="korruta.pl">Sisesta &uuml;ks arv:<BR>
<INPUT TYPE="TEXTBOX" NAME="x" SIZE="5"></INPUT>Sisesta teine arv:<BR>
<INPUT TYPE="TEXTBOX" NAME="y" SIZE="5"></INPUT>
<INPUT TYPE="SUBMIT" VALUE="Teele"></INPUT>
</FORM>

</BODY>
</HTML>
 

/home/imre/public_html/arvutaja.pl

#!/usr/bin/perl
print "Content-type: text/html\n\n";
$sisend=<STDIN>;
@d=split(/=|&/,$sisend);
print "Netscapelt sai programm sellise INUPUT'i:<BR> $sisend<BR>";
print "see lahutati neljaks komponendiks: $d[0], $d[1], $d[2], $d[3]<BR>";
$vastus = $data[1] * $data[3];
print "Tulemus<BR>$vastus";
 

Tulemusena peaks info

- browserist serverisse saadetame
- serveris töödeldatama (korrutatakse arvud)
- töödeldud info tagasi browserisse saadetama

Nagu näha saadeti info browserist serverisse õrnalt kodeeritud kujul. Tunnistage, et arve saata on kõige lihtsam. Teksti saata, mis korjatakse kokku mitmest kohast (vt. allpool) on keerulisem tagasi kodeerida. Ja suurem osa lihtsatest CGI programmidest tegelebki info kodeerimisega:

- browserist võttes kodeeritult tavalisel kujule
- browserisse saates tavalisest HTML foramaati

Ja sisuliselt ongi kogu CGI ära seletatud!

Ja üldistamiseks ütleme, et arvutaja.pl'i saab käivitada ka käsurealt ning ta arvutab:

imre@sygis ~/public_html$echo 'x=5&y=6' | arvuta.pl
Content-type: text/html

Netscapelt sai programm sellise INUPUT'i:<BR> x=5&y=6
<BR>see lahutati neljaks komponendiks: x, 5, y, 6
<BR>Tulemus<BR>0imre@sygis ~/public_html$

Normaalne ongi ehk käsurealt cgi asju nõnda testida. Läheb kiiremini, ehk. Ja üleltoodud alternatiivne käivitamise võimalus demonstreerib selgelt, et POST meetod loeb nö. standard input'i.
 
  Ja kokkuvõtteks toon ära joonise mis peaks kujutama serverit suhtluses kahe kliendiga (browseriga)



4. Apache serveri konfiguratsioon

Toodud näiteid on võimalik vaid siis edukalt rakendada kui server milles te kasutaja olete seda lubab. See sõltub administraatori vastutulelikkusest ja olukorrast. Selge on see, et lubades suvalistel inimestel (st. kõigil kodulehekülgede vaatajatel) serveris programme käivitada, pealegi isetehtud programme ei saa teha serverit töökindlamaks. Siiski, kui tahta täiesti turvalist serverit peaks ta üldse Internetist lahti ühendama :)

Netscape Location rea nö. päringutega tegeleb mitte terve server vaid selleks mõeldud programm (nö. daemon) Apache, sõpradele httpd. Tema annab browseritele nõutud kasutajate koduleheküljed ette. Samuti võib ta käivitada programme (so. CGI'sid).

Siinkohal ei söenda ma pikalt hakata arutlema Apache tööpõhimõtete üle. Praktiliselt on nii, et kogu konfiguratisoon asub kolmes failis kataloogis /var/lib/httpd/conf, seal on ka dokumentatsioon ja FAQ. MInul on need failid sellised:
 
 
 

imre@sygis /var/lib/httpd/conf$egrep -v "^#|^$" access.conf
<Directory /home/html>
Options Indexes FollowSymLinks ExecCGI Includes
AllowOverride None
order allow,deny
allow from all
</Directory>
<Directory /cgi-bin>
AllowOverride None
Options None
</Directory>
 
 

imre@sygis /var/lib/httpd/conf$egrep -v "^#|^$" srm.conf
DocumentRoot /home/html
UserDir public_html
DirectoryIndex index.html index.cgi index.pl
FancyIndexing on
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*
AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif core
AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^
DefaultIcon /icons/unknown.gif
ReadmeName README
HeaderName HEADER
IndexIgnore */.??* *~ *# */HEADER* */README* */RCS
DefaultType text/plain
AddEncoding x-compress Z
AddEncoding x-gzip gz
AddLanguage en .en
AddLanguage fr .fr
AddLanguage de .de
AddLanguage da .da
AddLanguage el .el
AddLanguage it .it
LanguagePriority en fr de
ScriptAlias /cgi-bin/ /home/cgi-bin/
AddHandler cgi-script .cgi .pl
AddType text/html .shtml
AddHandler server-parsed .shtml
 

imre@sygis /var/lib/httpd/conf$egrep -v "^#|^$" httpd.conf
ServerType standalone
Port 80
HostnameLookups on
User nobody
Group nogroup
BrowserMatch Mozilla/2 nokeepalive
ServerAdmin [email protected]
ServerRoot /var/lib/httpd
ErrorLog logs/error_log
TransferLog logs/access_log
PidFile logs/httpd.pid
ScoreBoardFile logs/apache_status
ServerName sygis.ee
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
MinSpareServers 5
MaxSpareServers 10
StartServers 5
MaxClients 150
MaxRequestsPerChild 30

 

No nii, vähemalt on olukord esitatad kuigi ilma kommentaarideta :)

Uurige ise järgi (Apache lehe pealt, ehk) mida mingi rida tegema peaks, aga tulemusena on minu Apache nõus

- käivitama .cgi ja .pl laiendiga faile kui nad asuvad all pool ~/public_html kataloogi
- vaatamata laiendile käivitatakse kõik failid mis asuvad /home/cgi-bin kataloogis
- SSI - Server Side Includes on lubatud, tõsi see ei puutu otseselt siia :)
 

5. SSI - Server Side Includes

Ma ilmselt ei tea kõiki SSI võimalusi,  mõned neist on sellised (Apachi konf vaata ülevalt):

1. html fail korjad oma sisu kokku tavalistest tekstifailidest (ASCII failidest)
2. kuvada keskkonnamuutujaid
3. saata teatud viivitusega browserisse teine URL

/home/imre/public_html/ssi.shtml

<HTML>
<HEAD>
<META HTTP-EQUIV="Refresh" CONTENT="23;URL=http://www.ee/www">
</HEAD>
<BODY>
Tere, 23 sekundi pärast lähete vaatama www.ee/www-d<BR><BR>
<!--#echo var="HTTP_HOST"--><BR>
<!--#echo var="REMOTE_ADDR"--><BR>
<!--#echo var="DOCUMENT_ROOT"--><BR>
<!--#echo var="SERVER_SOFTWARE"--><BR>
<!--#echo var="SERVER_PROTOCOL"--><BR>
<!--#echo var="REQUEST_METHOD"--><BR>
<!--#echo var="QUERY_STRING"--><BR>
<!--#echo var="SERVER_PORT"--><BR>
<BR>
<!--#include virtual="inc.txt"-->
</BODY>
</HTML>

NB! kuivõrd SSI koormab serverit, siis suhtub server html faili kui SSI'sse juhul kui laiendiks on shtml!
Toodud näide eeldab mingi tekstifaili inc.txt olemasolu ning ta võik laadida:

sygis.ee/~imre/ssi.shtml?tere_tere
 

6. Forms

Olles ülevalpool asja põhimõtteliselt ära seletanud või vähemalt kirjeldanud asume vaatama tehnilisi võimalusi info vahetamiseks browseri ja serveri vahel. Toome erinevate asjade kohta .html ja .pl failide paarid.

Forms ehk eesti keeles vormid, blanketid on sellised täidetavad/klõpsitavad interaktiivsused. Vaadake millised nad välja näevad ja samas on ka toodud html source:

1. textarea
2. checkbox
3.
 

7. pildi (jpg või gif) browserisse saatmine

Seda on kasulik teha kui peale pildi laadimise on vaja veel midagi toimetada. No tüüpiline on counter. Kui Netscapes on piltide laadimine lubatud, siis Netscape palub serveril kõik URL'i peal olevad pildid endale saata.  Kui aga on HTML-is on selline asi

<IMG SRC="http://sygis.ee/~imre/salaprogramm.pl">

siis käivitab Netscape selle programmi. Programm on vaja teha selline, et ta annab oma väljundisse pildile vastavad baitid kusjuures ta võib muudki teha. Counteri puhul nt. avab ta tekstifaili ja suurendab selle sisu ühe võrra ning sulgeb ta. Kokkuvõttes Netscape sai is tahtis ja uus kasutaja st. lehe laadimine on fikseeritud.
 

Konreetselt, et salaprogramm.pl toimiks vaid ildi saatjana võiks ta olla nt. selline:

/home/imre/public_html/salaprogramm.pl:

#!/usr/bin/perl
print "Content-type: image/jpeg\n\n";
$/=EOF;
open (fh, "pilt.gif");
while ($l=<fh>)
{
print "$l";
}
close (fh);

ning temaga samas kataloogis peab asuma ka pilt.gif.

õigused sellised:

bash# chmod 755 salaprogramm.pl
bash# chmod 755 pilt.gif

Kui aga ta peab pidama ka arvestust külastamise arvu üle, siis oleks lugu nii:

#!/usr/bin/perl
print "Content-type: image/jpeg\n\n";
$/=EOF;
open (fh1, "pilt.gif");
while ($l=<fh1>)
{
print "$l";
}
close (fh);
open (fh2, "korrad.txt");
$arv=<fh2>;
close (fh2);
open (fh3, ">korrad.txt");
$arv=$arv+1;
print fh3 "$arv";
close (fh3);

kusjuures peab olema veel lisaks külastusi lugev tekstifail korrad.txt prorammiga samas kataloogis.
korrad.txt'ga on see paha lugu, et sinna peavad saama kõik kirjutada. St. et sealt saavad ka kõik maha võtta.

bash# chmod 777 korrad.txt

Kui teil õnnestub aga administraatoriga koku leppida, siis on järgimine hea variant. Nimelt, Netscape serverisse pöördumist võib vaadelda kui kasutaja nobody kes kuulub gruppi nogroup sisselogimisena. Ja seega on hea anda käsud:

bash# chmod 755 korrad.txt
bash# chgrp nogroup korrad.txt
bash# chown nobody  korrad.txt

Arusaadavalt on kahe viimase käsu andmine vaid administraatori võimuses.
 

8. Interaktiivne kaart

See kõlab ehk liiga uhkelt, aga mis teha saab on see, et server saab teada kuhu kohta kaardil hiirega klõps tehti. Siit tulenevad rakendused:

- saab teada punkti koordinaadid (vasak ülanurk on 0, 0)
- saab arvutada lõikude pikkusi
- saab arvutada pindalasid

Vrd. Image Map HTML'i leheküljel. Neid koos kombineerides saab teha häid asju!
 

Näide:

Ekraanil on kaks raami, kusjuures koordinaadid on näha vasakus.

koordinaat.html:

<HTML>
<HEAD>
<FRAMESET COLS="20%, 80%">
        <FRAME SRC="vasak.html" NAME="v" BORDER=1>
        <FRAME SRC="parem.html" NAME="p" BORDER=1>
</FRAMESET>
</HEAD>
<BODY>
</BODY>
</HTML>

parem.html:

<HTML>
<BODY>

Tere<BR><BR>
<CENTER>
<A href="kaart.pl" TARGET="v">
<IMG SRC="http://sygis.ee/~imre/kaart.gif" ismap>
</A>
</CENTER>

</BODY>
</HTML>

vasak.html:

<HTML>
<BODY>
Olen ees vaid korra ...
</BODY>
</HTML>

kaart.pl:

#!/usr/bin/perl
print "Content-type: text/html\n\n<HTML><BODY>";
print "$ENV{'QUERY_STRING'}</BODY></HTML>";

On ka teine võimalus:

kaart.sh (erandina on see kirjutatud bash shellis):

#!/bin/bash
echo -e "Content-type: text/html\n\n<HTML><BODY>";
echo "$QUERY_STRING </BODY></HTML>";
 

Nagu näha liiguvad siin andmed keskkonnamuutujaga. Koma tuleb vahele automaatselt.

Ja muidugi on vaja anda sobivad õigused ja on vaja ka kaarti ennast kaart.gif.
___________________________________________
 
 

Tehniliselt on CGI'd mitte-CGI'st lihtsam eristada:

nimelt, kui Interneti browserisse (nt. Netscape) laadida koduleht www.ut.ee/~starylle/perl.html, siis võib toimuvat tõlgendada nii:

- user nobody kes kuulub gruppi nogroup logib ennast serverisse www.ut.ee sisse ja sattub kataloogi
/home/starylle/public_html mis on tema jaoks juurkataloog. St. piltlikult öeldes 'cd ..' ta sealt teaha ei saa.
- Netscape ekraanile viiakse perl.html faili sisule vastav väljund
- kui aga Netscape'is käivitada serveris mõni programm (eeldusel, et server seda lubab), siis on võimalik infovahetus kasutades teatud keskkonnamutujaid.

Ja nende keskkonnamuutujate kaudu infovahetamine ongi ainuke viis Netscape ja serveri vahel suhtelmiseks.

Ja muutujad ja nende väärtused võiksid olla näiteks järgmised:

HTTP_CONNECTION=Keep-Alive
HTTP_USER_AGENT=Mozilla/4.05 [en] (X11; I; Linux 2.0.34 i586)
HTTP_HOST=kopka.tkg.tartu.ee
HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg image/png
HTTP_ACCEPT_LANGUAGE=en
HTTP_ACCEPT_CHARSET=iso-8859-1,*,utf-8
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/samba/bin:/u
sr/X11R6/bin:/usr/andrew/bin:/usr/openwin/bin:.:/usr/games:/usr/local/src/teTeX/bin/i586-
linux:/usr/local/samba/bin:/usr/X11R6/bin:/usr/andrew/bin:/usr/openwin/bin:.:/usr/games:/
usr/local/src/teTeX/bin/i586-linux
SERVER_SOFTWARE=Apache/1.2.6
SERVER_NAME=kopka.tkg.tartu.ee
SERVER_PORT=80
REMOTE_HOST=s12.loss.eenet.ee
REMOTE_ADDR=193.40.28.112
DOCUMENT_ROOT=/home/html
[email protected]
SCRIPT_FILENAME=/home/cgi-bin/maria.b
REMOTE_PORT=1025
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.0
REQUEST_METHOD=GET
QUERY_STRING=
REQUEST_URI=/cgi-bin/maria.b
SCRIPT_NAME=/cgi-bin/maria.b

Ilmselt iga muutuja nimi kõneleb iseenda eest, aga rõhutame mõnda olulisemat:
 
CGI tereminites võib öelda, et kasutatakse vaikimisi andmete saatmist milleks on nn. GET meetod.

Programmile on eelpoolsaadetud sõna ka kättesaadev keskonnamuutujast $QUERY_STRING, seda kasutades näeks programm välja niisugune:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "$QUERY_STRING";
 

Kogu asja teeb keerulisemaks see, et targad ameeriklased on välja mõtelnud palju erinevaid võimalusi kuidas browserisse infot koguda enne kui see serverisse saata:

textarea - tekstikast (ka password)
dropdown list /scroll list- rippmenüü/kerimismenüü
radio buttons
checkbox
file upload

Ja nende omavaheline kombineerimine võimaldab saada huvitavaid tulemusi. Vaatame edaspidi asju konkreetsete näidete varal.
 
Ilmselt on lugejale juba teada see, kuidas teha kodulehekülgi, millistel kaalutlustel anda noile failidele õigusi. Nt. Netscape location rea täites

Location: server.ee/~imre/esileht.html

viib serverist browserisse faili /home/html/imre/public_html/esileht.html sisule vastava info. Tegelikult on CGI programmide kirjutamise ja kasutamise võimalustega väga seotud see kuidas on sätitud tööle web server - tavaliselt Apache. Seda kuidas Apachi tööle saada vt. Apache'i konfimise lehe alt. Peale Apache'i installeerimist on seal kataloogis (/var/lib/httpd/...) ka kasulikke õpetusi.
gggg