httpd

Funkce

Přístroj httpd umožňuje zpřístupnit (vizualizovat i řídit) aplikaci běžící v systému Control Web z libovolného WWW prohlížeče přes TCP/IP síť - ať už lokální intranet nebo celosvětový Internet. Přitom na straně klienta (WWW prohlížeče) není zapotřebí instalovat Control Web runtime ani žádnou jinou část systému Control Web. WWW prohlížeč také není zapotřebí doplňovat nebo rozšiřovat o speciální moduly (plug-ins, ActiveX). Rovněž nemusí (ale mohou) být použity Java applety, které jsou většinou velmi náročné na paměť, výkon procesoru a kapacitu přenosových linek. Veškerá funkčnost přístroje httpd je zajištěna čistě prostředky protokolu HTTP a HTML dokumentů. K přístupu k technologii přes rozhraní WWW tak lze použít jakýkoliv browser na jakékoliv platformě (Windows, Macintosh, UNIX, thin client, apod.).

Součástí přístroje httpd je plně funkční HTTP server integrovaný do systému Control Web. Protokol HTTP (HyperText Transfer Protocol) je celosvětově rozšířený protokol používaný k přenosu dokumentů i multimediálních informací v rámci internetové nebo intranetové služby označované jako World Wide Web (zkratka WWW). Podrobnou dokumentaci protokolu HTTP v1.1 lze nalézt v RFC 2068 (RFC je název souboru dokumentací Request For Comments, které je možno nalézt na celé řadě internetových serverů). Klient služby WWW (také označovaný jako WWW prohlížeč nebo anglicky WWW browser) vyšle požadavek (HTTP request) na danou informaci k serveru a server informaci vrátí (HTTP response). Identifikátor požadované informace má standardní tvar označovaný jako URI (Universal Resource Identifier). Součástí URI je identifikace protokolu (v našem případě http), adresa serveru a cesta k požadované informaci na serveru.

V naprosté většině případů označuje požadovaný URI soubor, který je serverem načten a vrácen do prohlížeče, který jej zobrazí. Nicméně soubor, na nějž URI odkazuje, nemusí vůbec existovat a server přesto může požadovanou informaci vrátit - může ji dynamicky vygenerovat až v době požadavku od klienta. Dynamické generování informace má velmi podstatnou výhodu -- požadovaná informace může přesně odpovídat požadavku klienta, což u staticky existujícího souboru nelze zajistit. Dokonce i v případě, že by byl soubor neustále obnovován, by tento mechanismus nedostačoval, protože v jednom okamžiku může danou informaci požadovat po serveru více klientů najednou, nehledě na časovou náročnost diskových operací.

Právě ve schopnosti dynamicky generovat informaci z jakýchkoliv dat zpracovávaných běžící aplikací systému Control Web spočívá dokonalá integrace HTTP serveru v přístroji httpd s celým systémem.

Přístroj httpd může pracovat jako standardní server pouze vracející klientům soubory z disku. Současně ale poskytuje další služby:

Ačkoliv HTTP je obecný protokol, který může pracovat nad jakýmkoliv síťovým protokolem, prakticky se HTTP používá jen ve spojení s internetovým protokolem TCP/IP. Přístroj httpd ke své funkci vyžaduje instalovanou podporu protokolu TCP/IP ve Windows.

Důležité upozornění: součástí definice internetového serveru je nutnost vlastnit stálou IP adresu. Počítač s adresou přidělovanou např. protokolem DHCP nemůže pracovat jako internetový server.

Přístroj httpd nikdy nezobrazuje přímo data z technologie a nenastavuje přímo datové elementy. Vždy je nutno explicitně zadat přemapování mezi světem aplikace a vnějším světem. Neexistuje tedy možnost zobrazit nebo nastavit hodnoty aplikace z WWW klienta nebo i speciálně napsaným programem, pokud je návrhář aplikace pomocí httpd přístroje nepřemapuje a tím nezveřejní.

Celému přístroji httpd lze nastavit úroveň přístupových práv. V takovém případě odmítne server poskytnout požadované informace a požaduje po klientovi zadání uživatelského jména a hesla. Toto jméno a heslo je porovnáno s databází uživatelů pracující aplikace systému Control Web (viz kapitola Systém přístupových práv uživatelů).

Syntax

  httpd httpd_name;
    rem = string;
    root_dir = directory_name;
    index_file = file_name;
    connections = number;
    ip_port = number;
    access = number;
    expressions
      expression_id = expression [ format_string | { value_string { , value_string } } ];
    end_expressions
    calls
      call_id = instrument_name.procedure_name( [ expression { , expression } ] );
    end_calls
    instruments
      instrument_id = instrument_name;
    end_instruments
    receivers
      receiver_id = instrument_name { , instrument_name };
    end_receivers
    forms
      form_id = data_element_name;
    end_forms
    form_receivers
      receiver_id = instrument_name { , instrument_name };
    end_form_receivers
  end_httpd;

Gramatika výrazů je shodná v rámci všech přístrojů celého systému Control Web.

Parametry přístroje

root_dir - kořenový adresář

Součástí URI je souborová cesta k požadované informaci. V definici HTTP je požadavek, aby cesta byla vždy absolutní, tedy aby obsahovala všechny adresáře počínaje kořenovým adresářem. Je ale velmi nepraktické a také potenciálně nebezpečné, aby se kořenový adresář prezentovaný HTTP serverem shodoval se skutečným kořenovým adresářem disku. Parametr root_dir dovoluje stanovit, který adresář na disku bude navenek prezentován jako kořenový. Z žádného klientského programu pak není možno přistoupit do jiné části disku.

Existuje-li struktura HTML dokumentů v adresáři 'C:\PUBLIC\WWW', pak parametr root_dir bude mít hodnotu:

    root_dir = 'c:\public\www';

Není-li adresář root_dir specifikován, přístroj httpd považuje za kořenový ten adresář, v němž je nalezen indexový soubor.

Cesta uvedená jako parametr root_dir může, ale nemusí končit opačným lomítkem.

Poznámka: Adresáře se v systému Control Web oddělují podle konvencí Windows znakem '\' (obrácené lomítko). Adresáře v zápisu URI jsou však odděleny znakem '/' (lomítko) podle konvencí systému UNIX. Server zpracovávající požadavek identifikovaný URI pak zaměňuje znaky '/' za '\', aby vytvořil zápis cesty platný v systémech Windows.

index_file - indexový soubor

Stalo se konvencí, že uživatel přistupující na WWW server poprvé nemusí zadat jméno základního HTML dokumentu. Namísto toho server dostane požadavek s cestou obsahující pouze kořenový adresář '/'. WWW server pak může mít v konfiguraci zadáno, jaký HTML dokument bude vrácen klientovi. Jméno tohoto souboru definuje parametr index_file.

    index_file = 'index.htm';

Není-li indexový soubor explicitně specifikován, přístroj httpd vyhledává v kořenovém adresáři nebo pokud není zadán podle přesměrování postupně tyto soubory:

Je-li tedy základní dokument struktury HTML dokumentů pojmenován výše uvedeným způsobem, není nutno parametr index_file zadávat.

connections - počet TCP/IP spojení

Tento parametr udává maximální počet současně otevřených TCP/IP spojení serveru. Pokud jsou všechna spojení aktivní, další požadavek na spojení bude pozastaven do doby, dokud není nějaké spojení ukončeno. Pro velmi zatížené servery je možno tuto hodnotu zvětšit nad implicitní počet 32 spojení. Naopak není-li žádoucí, aby HTTP server spotřebovával výkon počítače, je možné tento parametr zmenšit.

ip_port - port TCP/IP spojení

Protokol HTTP standardně (není-li číslo portu součástí URI) navazuje spojení na IP portu 80. Parametr ip_port umožňuje HTTP serveru zadat jiný IP port, na němž bude spojení navazováno. Pokud je např. definováno:

    ip_port = 8080;

pak spojení se serverem může být navázáno jen pokud klient uvede URI např.:

    http://www.controlweb.cz:8080/

access - úroveň přístupových práv

Pokud je v aplikaci Control Web definována hierarchie přístupových práv, je možno určit maximální úroveň přístupových práv, která ještě opravňuje uživatele k přístupu na WWW server. Je-li parametr access zadán, server odmítne zaslat klientovi data bez zadání uživatelského jména a hesla. Uživatelská jména a hesla jsou porovnávána s databází uživatelů definovaných pro danou běžící aplikaci.

Důležité upozornění: uživatelské jméno a heslo je v protokolu HTTP přenášeno pouze zakódované podle standardu mime base64, nikoliv zakryptované! Kdokoliv s přímým přístupem k datům přenášeným sítí může použitá přístupová jména a hesla vysledovat. Tato nedokonalost je obecná vlastnost protokolu HTTP.

expressions - přemapování výrazů

Výsledek jakéhokoliv výrazu aplikace Control Web může být umístěn do HTML dokumentu. Přístroj httpd před odesláním jakéhokoliv HTML dokumentu zkontroluje, jestli se v jeho textu nevyskytuje identifikátor definovaný v sekci expressions:

    expressions
      identifier_1 = a + b;
      identifier_2 = a > b;
      identifier_3 = concat( 'result = ', s );
    end_expressions;

Pokud je v textu dokumentu nalezen některý identifikátor, je nahrazen textovou reprezentací výsledku výrazu. Pak např. HTML text:

<dl>
  <dd>Součet proměnných a + b = <b>identifier_1</b>
  <dd>Proměnná a je větší jak b: <b>identifier_2</b>
</dl>

bude odeslán a klientem zobrazen jako (za předpokladu, že a = 10 a b = 15):

Součet proměnných a + b = 25
Proměnná a je větší jak b: Ne

Pokud by v textu byl použit také řetězec identifier_3, pak by byl nahrazen řetězcem 'result = ' a obsahem řetězce s.

Toto elementární nahrazování nemusí být vždy dostatečné. Proto za výrazem typu real může být formátovací řetězec:

    identifier_1 = sin( a / b ) * ln( c ); "##.####";

Formátovací řetězec může mít např. tvar masky, kde znak # nebo @ udává umístění a přesnost zobrazované numerické hodnoty. Jsou-li použity znaky #, místo případných nevýznamných nul před číslem jsou doplněny mezery, při použití znaků @ jsou v pevném formátu vypisovány i tyto nuly.

Boolean výrazy mohou nabývat pouze dvou hodnot, 0 (nepravda, FALSE) a 1 (pravda, TRUE). Přístroj httpd tyto hodnoty nahrazuje standardními řetězci 'Ne' a 'Ano'. Pokud tyto řetězce nevyhovují, je možno definovat vlastní řetězce pro "nepravdu" a "pravdu" do složených závorek za logický výraz:

    identifier_2 = a > b; {'a <= b', 'a > b'};

V takovém případě bude na základě výsledku výrazu a > b text identifier_2 nahrazen příslušným řetězcem. U logických výrazů musí seznam řetězců, pokud je uveden, obsahovat právě dva řetězce pro nepravdu a pravdu.

Seznam řetězců ve složených závorkách může však být uveden i za numerickým výrazem. Pak je výsledek výrazu převeden na celé číslo a identifikátor výrazu v HTML dokumentu je nahrazen prvním řetězcem, pokud je toto číslo menší nebo rovno 0, druhým výrazem, pokud je výsledek 1 atd. Pro hodnoty výrazu větší, než je největší index řetězce v seznamu, je použit poslední řetězec. Počet řetězců v seznamu musí být nejméně dva, jinak by transformace ztratila smysl.

Poznamenejme, že použití seznamu řetězců za numerickým výrazem se vzájemně vylučuje s použitím formátovacího řetězce.

Důležité poznámky:

calls - přemapování volání procedur

I když nahrazování identifikátorů (textových podřetězců) na základě vyhodnocení výrazů je dostatečné pro celou řadu případů, existují situace, kdy tento způsob není použitelný -- zejména pokud délka nově generovaného textu není dopředu známa a nelze ji popsat přímo v HTML dokumentu. Typickým příkladem může být generování tabulky s předem neznámým počtem řádků, např. při konverzi výsledků databázového dotazu do podoby HTML dokumentu.

Přístroj httpd stejně jako v případě přemapovávání výrazů vyhledává v HTML dokumentu výskyt identifikátorů uvedených v sekci calls. Pokud je daný identifikátor nalezen, je vyvolána procedura zapsaná u odpovídajícího identifikátoru:

    callss
      _put_table_ = self.GenerateTable( NumberOfLines );
      _put_list_  = self.GenerateList( NumberOfLines );
    end_callss;

I když je možné volat libovolnou proceduru libovolnému přístroji, v ukázce je použito na místo jména přístroje klíčové slovo self, které nahrazuje jméno přístroje httpd samotného. Volání procedur přístroje samotného má smysl zejména proto, že ke tvorbě textu, jímž bude nalezený podřetězec nahrazen, je nutno použít nativních procedur daného přístroje httpd.

Volané procedury mají ke generování textu, jež nahradí odpovídající identifikátor, k dispozici dvě nativní procedury přístroje httpd:

Tyto procedury je možné libovolně volat v rámci procedury volané při odesílání HTML dokumentu. Procedura GenerateTable z předchozího příkladu tak může vypadat například následovně:

    procedure GenerateTable();
    var
      i = real, 0;
      s = string, '';
    begin
      self.PutHTML('<table border = "1">');
      for i = 1 to lines do
        s = concat('<tr><td> line </td><td> ', str( i, 10 ));
        s = concat( s, ' </td></tr>');
        self.PutHTML( s );
        self.PutCRLF();
      end; (* for *)
      self.PutHTML('</table> ');
    end_procedure;

Při práci s procedurami volanými v rámci generování HTML stránek platí následující pravidla:

instruments - přemapování přístrojů

Přístroj httpd dokáže vrátit klientovi grafickou podobu každého zobrazitelného přístroje v běžící aplikaci jako obrázek. Pokud má být nějaký přístroj zobrazován v HTML dokumentu, je nutné jej přemapovat v sekci instruments:

    instruments
      _instrument_ = meter_2;
    end_instruments;

pak je monžno do HTML dokumentu umístit odkaz na obrázek _instrument_:

<IMG SRC="_instrument_">

Soubor jména _instrument_ nikde na disku samozřejmě neexistuje. Přístroj httpd v paměti vytvoří momentální podobu přístroje meter_2 a vrátí ji klientovi.

Zobrazit tak lze každý v principu viditelný, nikoliv momentálně viditelný přístroj. I pokud je např. panel momentálně skryt nebo překryt jiným panelem, httpd jej správně vrátí klientovi. Nelze ale vrátit např. podobu přístroje program.

Přemapovávání vzhledu přístrojů používá API funkce Windows GetDIBits(), která nemusí zejména ve Windows 95/98 pracovat korektně. Naneštěstí tuto nekorektnost nelze jednoduše zjistit. Pokud váš operační systém (a ovladač obrazovky) tuto funkci nepodporuje, aplikace obsahující přístroj httpd přemapovávající vzhled přístrojů nepůjde spustit. V naprosté většině případů se ale tato nefunkčnost projeví až za běhu. V takovém případě je na místo obrázku vrácen informační text popisující daný problém. Řešení je několik:

Pokud konfigurujete počítač, na němž poběží aplikace s HTTP serverem, použití barevné hloubky 256 barev odlehčí operačnímu systému práci s přemapováváním přístrojů a zvýší výkon.

receivers - přemapování příjemců zpráv

Jednotlivé virtuální přístroje systému Control Web jsou většinou aktivovány na základě časového kroku nebo události zaslané jiným přístrojem. Přístroj httpd je ale aktivován požadavkem klienta. Přesto může vzniknout potřeba vykonat nějaké akce v závislosti na zpřístupnění HTML dokumentů. K tomu slouží sekce receivers přemapovávající identifikátory na seznamy aktivovaných přístrojů:

    receivers
      _activate_id1_ = meter_3, program_2, archiver_5;
      _activate_id2_ = pressure_1, pressure_2;
    end_receivers;

Před odesláním každého dokumentu přístroj httpd prohledá text a pokud nalezne nějaký identifikátor přemapovávající seznam přístrojů, aktivuje všechny přístroje uvedené v seznamu. Oproti seznamu receivers v ostatních přístrojích se aktivace provede ještě před přemapováváním přístrojů a výrazů a vrácením dokumentu klientovi.

Vzhledem k tomu, že identifikátory nemají pro uživatele informační význam, je vhodné umístit je v HTML dokumentu do komentářů:

<!-- _activate_id1_ -->

Vytvořit počítadlo přístupů na danou stránku je tak velmi snadné:

Část kódu aplikace Control Web:

var
  counter = real, 0;
end_var

instrument

  program increment;

    procedure OnActivate();
    begin
      counter = counter + 1;
    end_procedure;

  end_program;

  httpd www_server;
    expressions
      _counter_ = counter;
    end_expressions;
    receivers
      _increment_ = increment;
    end_receivers;
  end_httpd;

end_instrument;

HTML dokument:

<!-- _increment_ (identifikátor aktivující program increment) -->
<HTML>
<HEAD>
<TITLE>Ukázka počitadla stránek</TITLE>
</HEAD>

<BODY>
Počet přístupů: <b>_counter_</b>
</BODY>
</HTML>

forms - přemapování vstupů z formulářů

Součástí jazyka HTML je možnost vracet data od uživatele zpět serveru. Není možno v této dokumentaci popisovat formuláře HTML, kompletní popis HTML lze nalézt např na serveru http://www.w3c.org/. V principu se ale veškerá data z formulářů vrací v podobě textových řetězců jméno_ovládacího_prvku=hodnota pro všechny platné ovládací prvky (controls) na stránce. Sekce forms mapuje identifikátor ovládacího prvku na datový element:

    forms
      ctrl_1 = a;
      str_2  = s;
    end_forms;

Pak bude-li v nějakém formuláři ovládací prvek jménem ctrl_1, přístroj httpd se po přijetí dat z HTML formuláře pokusí převést hodnotu přiřazenou tomuto ovládacímu prvku na datový typ shodný s typem datového elementu (proměnné, kanálu) a pokud se to povede, hodnotu do datového elementu přiřadí. Pravidla pro převod jsou následující:

Data z formulářů lze serveru vracet pomocí dvou typů HTTP zpráv: GET a POST. HTTP server přístroje httpd akceptuje obě metody, chová se ale poněkud odlišně:

Poznamenejme, že u metody GET se návratové hodnoty kódují metodou urlencoding a vracejí se jako součást řetězce URI, který má omezenou délku. Data z dlouhých formulářů se tak nemusí vrátit celá. Délka dat vracených metodou POST není omezena.

form_receivers - přemapování příjemců zpráv z formulářů

Sekce form_receivers je syntakticky shodná se sekcí receivers a slouží také k aktivaci přístrojů. Identifikátor seznamu aktivovaných přístrojů ale není vyhledáván v textové podobě stránky, ale přístroj httpd jej porovnává s hodnotami ovládacích prvků vrácených z formulářů. Nedochází tedy k aktivaci před odesláním stránky ale po přijetí dat z formuláře.

Vzhledem k tomu, že identifikátory jsou vyhledávány v návratových hodnotách, nikoliv ve jménech ovládacích prvků, lze z formuláře podmíněně aktivovat různé přístroje podle hodnoty ovládacích INPUT prvků např. text, radio nebo prvků SELECT. Pokud je pouze požadována nepodmíněná aktivace virtuálních přístrojů po příjmu dat z formuláře, lze s výhodou použít ovládacího prvku INPUT typu hidden. Takový ovládací prvek není zobrazen, ale je vrácen spolu se jmény a hodnotami ostatních prvků formuláře.

Typickým použitím aktivace z formuláře je promítnutí hodnot zpět do přístrojů systému. Je-li z formuláře např. změněna hodnota nějaké proměnné současně zobrazované přístrojem typu meter, pak je vhodné tento přístroj aktivovat, aby se překreslil a reagoval tak na změnu.

Nativní procedury přístroje

GetCurrentConnections( &Connections : number )

V parametru Connections je vrácen aktuální počet TCP/IP spojení. Vzhledem k bezstavové podstatě protokolu HTTP ale nelze usoudit na aktuální počet uživatelů. Podle zavedených pravidel by klient neměl otevírat více jak dvě spojení na server současně, nic ale nezabrání klientovi toto doporučení nerespektovat. Dále je nutné si uvědomit, že spojení je navázáno jen v době přenosu stránky, protokol HTTP neudržuje spojení mezi jednotlivými přenosy.

GetTotalURLs( &TotalURLs : number )

V parametru TotalURLs je vrácen počet všech odeslaných dokumentů včetně obrázků apod.

GetTotalInstruments( &TotalInstruments : number )

V parametru TotalInstruments je vrácen počet přemapovaných virtuálních přístrojů odeslaných v podobě bitových map.

PutHTML( s : string )

Procedura používaná ke generování HTML textu v rámci jiných procedur uvedených v sekci calls. Textem postupně předávaným v parametru s je nahrazován identifikátor odpovídající danému volání v sekci calls.

PutCRLF()

Procedura se používá podobně jako PutHTML(...), do HTML dokumentu ale generuje sekvenci znaků CR a LF.

Událostní procedury přístroje

Přístroj může volat standardní událostní procedury:

OnActivate()

Podrobnější informace k těmto procedurám lze nalézt v kapitole Programování a procedury.

Specifické událostní procedury přístroje

Přístroj nevolá specifické událostní procedury.