C-SaCzech Procedura EncodeFile

Do proměnné pagefile si zkopíruje obsah proměnné PATH_TRANSLATED, která by měla obsahovat cestu, která vede k dokumentu zadanému jako parametr. Zda se jedná od adresář zjišťuje podmínka
if ( isdir(pagefile) )
kde isdir je funkce definovaná v <www.h>. Pokud je to tedy adresář, připojí se na konec pagefile jméno souboru, který má být uživateli předložen v takovém případě (typicky index.html). Výsledkem je naplnění proměnné pagefile jménem souboru, který má být překódován a odeslán uživateli.

Ukazatel b je nastaven tak, aby ukazoval na začátek přípony překládaného souboru (resp. na znak za poslední tečkou v názvu souboru).

Kódovat či nekódovat

Fundamentálním rozhodnutím v životě procedury je, zda soubor patří do jeho kompetence. O to se stará test
if ( ISEXT(b) )
Pole ext obsahuje typy (hodnoty HTTP hlavičky Content-Type), přiřazené příponám, které mají být kódovány. Implicitně se C-SaCzech stará jen o soubory s příponami html, htm (typ text/html) txt (typ text/plain) a cz (typ text/html). Chcete-li změnit sortiment zpracovávaných přípon, musíte na začátku souboru csaczechXX.c změnit pole ext a znovu instalovat C-SaCzech.

Má-li přípona souboru v poli ext přiřazen typ, bude programem zpracována. V opačném případě (a také tehdy, pokud soubor nemá příponu) pošle procedura jako odpověď klientovi přesměrování (s využitím HTTP hlavičky Location) přímo na soubor - vynechá z URL sám sebe. Klient se po této odpovědi obrátí znovu na WWW server s novým URL souboru, které již neobsahuje volání kódujícího programu. To samozřejmě znamená jisté zpoždění. Sekvence dotaz-přesměrování-dotaz-odpověď je jistě pomalejší než dotaz-odpověď. Ovšem zpoždění, způsobené přesměrováním a novým dotazem, je zpravidla zanedbatelné ve srovnání s přepravní dobou dokumentu.

Alternativním řešením by bylo, aby program klientovi rovnou odpověděl a poslal mu soubor v původním znění beze změny kódování. Tento přístup má dva velmi závažné nedostatky.

  1. Klient musí v hlavičkách odpovědi zaslat typ dat (Content-Type). K tomu, aby mohl zasílat správné typy pro všechny možné soubory, musel by být konfigurován pro všechny možné i nemožné přípony - stejně jako je WWW server. Změna ve struktuře přípon by znamenala změnu konfigurace WWW serveru i C-SaCzech. To je pracné a hrozí nekonzistence.
  2. Odesílaný soubor by byl "nově vytvořen" - jednalo by se o výstup z CGI skriptu. Tím be se efektivně zlikvidoval účinek vyrovnávacích pamětí.
Z těchto dvou důvodů považuval autor SaCzechu přesměrování za výhodnější řešení a mě nezbývá než souhlasit.

Když se kóduje

Jestliže procedura zjistí, že se kódování nevyhne, otevře soubor a zavolá MakeHeaders, který vytvoří hlavičky odpovědi. Poté se může pustit do práce. Celý proces kódování probíhá po řádcích. Zpracování jednoho řádku je obsaženo v těle cyklu
while(fgets(buff, 512, fd )!=NULL)
Nejprve se podívejte na jeho závěr, kde najdete volání procedury EncodeLine. To je jádro celého C-SaCzechu, zajišťující vlastní změnu kódu. Je to vlastně alias, ve skutečnosti se volá
cs_encode( XX, source, target )
kde source je zdrojové a target cílové kódování. Procedura cs_encode je definována v souboru <cstools.h>. Dělá to, že si vytvoří hešovací tabulku pro převod z jednoho kódu do druhého a potom postupně převede každý znak ze vstupního řetězce.

Vraťme se teď zpět na začátek těla zpracovávajícího cyklu. Jestliže se na řádku vyskytuje slovo CHARSET, provede se tělo podmíněného příkazu. V něm se zajišťují dvě operace. Řádek

subs( buff, "__CHARSET__", TRUENAME(target) );
zajistí nahrazení řetězce __CHARSET__ jménem kódu, do kterého se dokument převádí.

Následuje pasáž, která umožňuje nastavení výchozího kódu. Program jí prochází jen v případě, že řádek obsahuje řetězece MYCHARSET. V tom případě se zavolá procedura newsource, která zajistí korektní přečtení a rozpoznání názvu kódu, do kterého se chce dokument přepnout. Jestliže se jedná o některé ze jmen podporovaných kódů, přenastaví se proměnná source, jinak se nastaví zpátky na default hodnotu.

MakeHeaders

Tělo tohoto podprogramu je velmi variabilní a závisí na nastavení konfiguračních voleb timeservices a ifmodifiedsince. Pokud vypnete první z nich, bude tělo degradováno na prosté příkazy
  for(i=0; i<4; i+=2)
    if ( !strcasecmp(extt, ext[i] ) ) break;
  printf( "Content-Type: %s\r\n", ext[i+1] );
  printf( "\r\n" );
které na základě přípony souboru vytvoří hlavičku Content-Type s odpovídajícím typem.

Jestliže při instalaci byla zapnuta volba TIMESERVICES, je práce procedury mnohem náročnější. Na jejím začátku se naplní centrální struktura buff voláním funkce stat a struktura tmi časem modifikace požadovaného souboru.

Následuje (pokud jste to nezakázali volbou IFMODIFIEDSINCE) podmíněný příkaz, obsluhující podmíněné odeslání souboru. Jestliže dotaz obsahoval HTTP hlavičku If-Modified-Since a soubor není novější, odpoví program stavovým kódem 304 Not Modified a ukončí svou činnost. V opačném případě pokračuje normálně dál. Část programu v těle podmíněného příkazu začínajícího

if ( g == a || b[3] == *a || &b[3] == g )
zajišťuje převod časového údaje (měl by rozeznávat všechny tři tvary, povolené podle RFC 1866, stejně jako původní SaCzech ) na vnitřní tvar, používaný C-SaCzechem.

Po hlavičce Content-Type pak skript vytvoří ještě Content-Length a Last-Modified podle údajů, které získal na začátku podprogramu při volání stat.


ZPET Zpět

Tato stránka je součástí dokumentace programu C-SaCzech.