Co je to CGI skript?
CGI skript je vámi vytvořený program, který umožní generovat dynamické WWW stránky, tj. stránky, které mohou vypadat při každém jejich otevření jinak. Obsah může být závislý na aktuálním času, obsahu různých souborů, adrese počítače, ze kterého je stránka navštívena atd.
Jak vytvořit CGI skript
CGI skript je jakýkoliv (na straně serveru) spustitelný soubor (obvykle však skript – odtud pojmenování), který po spuštění na standardní výstup vypíše HTTP hlavičku stránky (nezaměňujte s HTML hlavičkou) a poté její vlastní obsah. Může jít o klasický text v HTML, ale také jakékoliv jiný typ dat.
Skript by měl vygenerovat minimálně hlavičku Content-Type:
následovanou prázdným řádkem, který označuje konec hlavičky. Příklad jednoduchého CGI skriptu napsaného v shellu bash
:
#!/bin/bash
echo "Content-Type: text/html"
echo
echo "<body>"
echo "my first example page \o/"
echo "<pre>"
date
echo "</pre>"
echo "</body>"
Zde /bin/bash
je celá cesta k interpretu, který má na serveru skript spustit. Může to být Bash, Perl, PHP nebo leccos jiného. Dejte si však pozor, pokud své stránky a skripty píšete v editorech či na systémech, kde se vám na konec řádků ukládá i znak CR
(Ctrl-M, ^M) – typicky windowsové programy. Pak by se hledal nikoliv program bash
v adresáři /bin
, ale jakýsi program bash^M
, který samozřejmě neexistuje.
Content-Type:
je v tomto případě text/html
, což pro WWW server znamená, že CGI skript generuje HTML stránku. Pokud by skript generoval např. obrázek, Content-Type
by byl, řekněme, image/gif
.
CGI skript musí být spustitelný na Aise. Aby WWW server rozpoznal, že jde o CGI skript, musí mít skript příponu .cgi.
Uživatelské CGI skripty dostupné pod /~xlogin/
CGI skript musí být spustitelný vlastníkem, což zajistíte příkazem:
chmod u+x ~/public_html/script.cgi
Pokud se nejedná o binární program, ale skutečně o skript, je potřeba také nastavit právo pro čtení vlastníkem.
Skripty jsou spouštěny pomocí mechanismu suexec, který umožní provádění skriptu pod identitou vlastníka. Zároveň také kontroluje některé bezpečnostní podmínky. Základem je: skript musí patřit uživateli, který je uvedený v URL (https://www.fi.muni.cz/~xlogin/
) a skupině, kterou má tento uživatel jako primární (lze zjistit příkazem id
). Skript ani nadřazený adresář nesmějí mít povolen zápis pro skupinu a ostatní.
Suexec svoji činnost loguje do souboru /var/log/httpd-user/suexec
.
V případě nesplněných bezpečnostních podmínek se zde dočtete konkrétní příčinu selhání.
CGI skripty uložené mimo strom /~xlogin/
Tyto CGI skripty musí být spustitelné (oprávnění
) uživatelem apachefi; pokud se nejedná o binární program, ale o skript, je potřeba mít nastaveno i právo pro čtení (x
) uživatelem apachefi. To lze dosáhnout příkazem r
setfacl -m u:apachefi:r-x script.cgi
. Spouštěné CGI skripty běží pod identitou uživatele apachefi
, a tomu je tedy potřeba přizpůsobit i chování skriptu. Typicky například tento uživatel může zapisovat pouze do adresáře /tmp
.
Speciální proměnné v CGI skriptech, práce s parametry v URL
WWW server nastaví několik nových proměnných, se kterými můžete v CGI skriptu pracovat. Které to jsou, můžete zjistit podle příkladu uvedeného v sekci o ladění CGI skriptů.
Speciálně, pokud předáváte CGI skriptu parametry (metodou GET), budou dostupné v proměnné QUERY_STRING
. V shellovém CGI skriptu může zpracování parametrů vypadat třeba takto:
#!/bin/bash
. /packages/run.64/bashlib-0.4/bin
echo Content-type: text/plain
echo
HOST=$(param host)
/usr/bin/host $HOST
Tento program uloží do proměnné HOST
hodnotu parametru host
.
Pokud tedy program zavoláte pomocí URL
https://www.fi.muni.cz/~xlogin/this_script.cgi?host=aisa
,
bude jeho výstupem výstup příkazu host aisa
.
(Více o bashlib na bashlib.)
Pokud parametry předáváte metodou POST
, jsou data předána na standardní vstup CGI skriptu.
CGI skripty a bezpečnost
Je důležité si uvědomit, že pokud je spouštěný CGI skript vyvolán v podstromu /~xlogin/
, běží pod vaší identitou. Pokud tedy uděláte ve skriptu nějakou bezpečnostní chybu, může dojít i ke ztrátě/změně vašich dat na serveru či jinému zneužití vaší identity. Proto si před uveřejněním skript vždy důkladně zkontrolujte a počítejte s tím, že se možná někdo bude snažit robustnost a odolnost vašeho skriptu vlastnoručně prověřit. To se týká obzvlášť zpracování parametrů.
Rovněž mějte na paměti, že příklady uváděné na této stránce jsou pouze ilustrační (byť funkční) a nemusí být napsány bezpečně. Než začnete psát CGI skripty, doporučujeme přečíst si o této problematice něco na webu.
Ladění CGI skriptů
Doporučujeme předně zkusit CGI skript spustit z příkazové řádky přímo na Aise. Zde můžete odchytit např. chybová hlášení interpretu. Je velice pravděpodobné, že po spuštění pod uživatelemapachefi
nebude mít skript nastavené některé proměnné prostředí (typicky PATH
, LD_LIBRARY_PATH
, ...). Aktuální stav proměnných při běhu CGI skriptu vám zjistí například tento kód:
#!/bin/bash
echo "Content-type: text/plain"
echo
set
Ladění Perlových skriptů:
- Používejte
use CGI
, což umožní ladit skripty i na příkazové řádce, včetně parametrů. - Používejte
use CGI::Carp qw(fatalsToBrowser)
, což zobrazí chybové hlášky do prohlížeče.
Ladění shell skriptů:
- Hned za úvodní
#!/path/to/interpreter
(např.#!/bin/bash
) přidejte řádekexec 2>/home/xlogin/public_html/stderr.log
, který přesměruje chybový výstup do souboru. - Používáte-li moduly, je potřeba je nejdříve inicializovat. Více podrobností najdete na stránce o modulech.
Co dělat, když to stále nefunguje:
- Znovu si přečíst tuto stránku.
- Znovu překontrolovat, jestli máte správně nastavená přístupová práva na adresáři
~/public_html
a vnořených (pro detaily viz stránku o uživatelských HTML stránkách. - Znovu překontrolovat, jestli má CGI skript příponu
.cgi
. - Znovu překontrolovat přístupová práva na CGI skriptu a jeho relevantním okolí.
- Znovu si zkusit CGI skript spustit ručně na Aise z příkazové řádky.
- Pokud skript funguje na příkazové řádce, ale ne při přístupu přes WWW, podívat se do logů WWW serveru po možné příčině. Kde jsou uložené logy?
- Poradit se se zkušenějšími kolegy.
- Poradit se se správci.