HOME > HOWTO > PROGRAMOVÁNÍHOWTO

C a CGI skripty

24. Květen 2000, 00:00 (11826x zobrazeno)

Jazyk C nebyl vytořen k psaní CGI skriptů a je to znát. "Holé" C nemá porovnávání pomocí vzorů (jako např. Perl), nemá přímo přístup k proměnným z HTML formulářů (jako např. PHP). Jeho velkou výhodou je ale to, že narozdíl od Perlu a PHP je to jazyk kompilovaný, takže po přeložení do binární podoby při svém běhu spotřebuje daleko méně systémových zdrojů a je rychlejší.

CGI skript je v podstatě obyčejný program, jehož výstupem je HTML kód. Používá se pro generování dynamických stránek, např. pro výstup z databáze apod. CGI skripty bývají většinou umístěné na serveru v adresáři /cgi-bin/. Pokud používáte Apache, je potřeba v jeho konfiguračních souborech pro adresáře, kde budou umístěné CGI skripty zadat direktivu ExecCGI a dále definovat příponu (např.) cgi jako příponu CGI skriptů.

Do souboru httpd.conf je tedy potřeba přidat (samozřejmě upravené podle vaší konfigurace) tyto řádky:

AddHandler cgi-script .cgi

ScriptAlias /cgi-bin /home/httpd/cgi-bin

<Directory "/usr/www/cgi-bin">
  AllowOverride None
  Options ExecCGI
  Order allow,deny
  Allow from all
</Directory>

Většinou už Apache takto nastaven je a nebo stačí "odkomentovat" příslušné řádky. Soubor s CGI skriptem musí být pro server spustitelný.

Server posílá výstup z CGI skriptu přímo prohlížeči a ten ho zobrazí. Pokud pošlete na výstup přímo HTML kód, prohlížeč ho zobrazí tak jak je (tedy všechny tagy apod.), což určitě nebylo cílem. Server (Apache, MSII) a klient (Netscape, Explorer) totiž spolu komunikují protokolem HTTP. Tento protokol má "hlavičky" ve kterých server klientovi kromě jiného zděluje jaký formát mají data, která mu posílá. První řádka výztupu z CGI skriptu by proto měla být:

puts("Content-type: text/html\n");

Toto je nejjednodušší možná hlavička, která říká klientovi, aby očekával HTML stránku. Samozřejmě jinou hlavičku použijete, pokud budete generovat textový výstup a nebo obrázek (např. GIF). Důležité je, že za hlavičkou vždy musí následovat prázdný řádek. Ve zkutečnosti to není celá hlavička, ale server už její zbytek (začátek) doplní sám. A to je, co se týče výstupu v podstatě všechno. Pak již může následovat výstup www stráky:

puts("<HTML>");
...

Vstup do CGI skriptu je podstatně složitější. Vstupem jsou zde myšlena data, která CGI skript dostane z nějakého HTML formuláře a nebo z URL adresy. HTML formulář je kousek kódu www stránky a vypadá například takto:

<FORM NAME="formular" ACTION="/cgi-bin/sktipt.cgi" METHOD="get">
<INPUT TYPE="text" VALUE="hodnota" NAME="polozka">
<INPUT TYPE="hidden" VALUE="hodnota2" NAME="skrite">
<INPUT TYPE="submit" VALUE="Odeslat">
</FORM>

První řádka říká klientovi, na jakou adresu (ACTION) a jakým způsobem (METHOD - viz dále) má poslat data z formuláře. Druhá je obyčejné textové políčko pro vstup. Třetí je skrytý údaj, který bude poslán. Používá se například pro zjištění z které stránky byla data poslána (pokud jsou formuláře na různých stránkách) a nebo v dynamicky generovaných stránkách se může využít k přenášení informací např. o uživateli - protokol HTTP je totiž bezestavový a informace si nelze nijak zapamatovat, jedině pomocí hidden proměnných ve formulářích a nebo pomocí cookies.

Existují dva základní způsoby, jak předat serveru (CGI skriptu) data z formuláře: metoda GET a metoda POST (viz první řádka předchozího příkladu). Pokud použijete GET, klient data zahrne do URL adresy požadavku a ta pak bude ve tvaru:

http://vas-server/cgi-bin/skript.cgi?polozka=hodnota&skryte=hodnota2

Tedy na konci adresy CGI skriptu je otazník a pak následují ampersandem oddělené dvojice položka=hodnota. CGI skript v C pak může tyto data načíst z proměnné prostředí QUERY_STRING. Při použití metody POST jsou data zakódovaná stejným způsobem, ale nezobrazují se v URL. Server je kopíruje přímo na vstup CGI skriptu. Délku dat lze zjistit z proměnné CONTENT_LENGTH. Aby to nebylo tak jednoduché, jsou data ještě kódována. Některé speciální znaky, jako je +, /, ? jsou kódovány do tvaru %xx, kde xx je dvoumístný hexadecimální kód znaku (podle ASCII tabulky). Mezera je pak kódována jako "+". Takže například řetězec "hurá hurá" se zakóduje na "hur%E1+hur%E1". O tom jaká metoda byla použita se CGI skript dozví z proměnné REQUEST_METHOD.

Každá metoda mé své výhody a nevýhody. Nevýhodou GET je, že délka takto přenášených dat je omezena (klienti neumí pracovat s libovolně dlouhou adresou) a že jsou všechna data "vidět" v URL adrese, což poněkud snižuje soukromí. Naopak její výhodou je, že url adresu včetně dat je možné použít jako normální odkaz. Naproti tomu hlavní výhodou metody POST je možnost přenést velké množství dat (zkoušel jsem přenosy souborů o délce desítek KB).

K dekódování dat můžete buď použít různé knihovny, které lze najít na internetu (uncgi, libcgi) a nebo si napsat vlastní funkce (tuto cestu jsem volil já a není to nic až tak obtížného). Protože klient odesílaná data nijak nekontroluje, je třeba ošetřit případy kdy není posíláná žádná hodnota proměnné (např. ...cgi?polozka=&polozka2=neco) a nebo je jedna položka poslaná několikrát. Takto lze přenášet i data získaná z formuláře z různých checkboxů a radiobutonů a nebo z rolovacích menu.

No a nakonec příklad, jak vlastními silami načíst data z formuláře. Ukázka rozpozná zda jsou data zaslaná pomocí GET nebo POST a načte je:

#include 
#include 
#include 

int main(void)
  {
  /* nacteni typu metody */
  char *metoda = getenv("REQUEST_METHOD");
  /* zde budou data z formulare */
  char *cgi;
  int delka;
  
  /* je-li to GET, nacti data z QUERY_STRING */
  if (!strcmp(metoda, "GET"))
    {
    cgi = strdup(getenv("QUERY_STRING"));
    }
   
  /* je to POST, nacti je ze vstupu */  
  else
    {
    /* nacti delku dat */
    delka = atoi(getenv("CONTENT_LENGHT"));
    
    /* alokuj pamet + 1B na ukonceni */
    cgi = (char *) malloc(delka + 1);
    
    /* nacti data */
    fread(cgi, delka, stdin);
    
    /* ukonceni retezce znakem \0 */
    cgi[delka] = 0;
    }
  
  /* tisk retezce */
  puts(cgi);
  
  return (0);
  }

Berte prosím tohle jako ukázku, kterou není vhodné bez úprav použít, chybí zde kontrola chyb, ošetření případu, kdy se nebude jednat o metodu GET ani POST (protokol HTTP definuje cca 10 různých metod), uvolnění alokované paměti a další.

autor: Ing. Jiří Václavovič

Líbil se vám článek?

5 (3x hodnoceno)12345

Komentáře

HACKER SITES  SEZNAMKA PRAHA  LUHILL DESIGN WEAR  STREET Wear LuHill PRAGUE  www.czfree.net  Hack This Page  RYCHLE RANDE V PRAZE  DETSKA SKOLKA - STODULKY - PRAHA 13  www.BASTARDSERVERS.com  DEBIAN GNU LINUX 
www.blackhole.cz  www.linux.sk  www.abclinuxu.cz  www.underground.cz  www.zi.cz  SEZNAMKY PRAHA - RYCHLORANDE  www.linuxzone.cz  www.root.cz  www.penguin.cz  www.krypta.cz 
HACKER T SHIRTS  RYCHLE SEZNAMOVANI  HELL toplist  www.BASTARDSERVERS.com  G$BIT SERVERS  geek music  www.soom.cz  TRICKA A MIKINY PRAHA  HackThisPage  BABBY SITTING - BABY DAY CARE- PRAHA 13 
GEEK T-SHIRTS  BABYSITTING PRAHA 13  photopost.cz  apsara.cz  RANDIX HLIDANI DETI V PRAZE  sport, outdoor, cyklo obchod  dfklub.cz  www.zi.cz  Moderni seznamovaci agentura RANDIX  DETI - HLIDANI