WWW, HTTP servery

Marek Rychlý, xrychly1(at)fi.muni.cz


Obsah


WWW (World Wide Web)

WWW je síťová služba typu klient-server, založená na třech techonogiích: komunikačním protokolu HTTP, adresování dokumentů URL a jazyku dokumentů (X)HTML.

Protokol HTTP, hlavičky

HyperText Transfer Protocol (HTTP) je síťový protokol aplikační vrstvy, který používají klient a server pro vzájemnou domluvu. Jedná se o bezstavový protokol. Klient posílá na server dotaz a server vrací odpověď, přičemž se každý dotaz posuzuje zcela samostatně (dotaz–odpověd tvoří ucelenou transakci). V současné době máme tři verze protokolu HTTP (první verze se již nepoužívá):
HTTP v0.9pouze pro zasílání čistých dat, dotazu a odpověď bez hlaviček a metainformací (zejména bez určení délky a typu dat) – dnes se nepoužívá.
HTTP v1.0formát dotazu a odpovědi doplněn po vzoru SMTP, podle standardu MIME (Multipurpose Internet Mail Extension) – hlavičky popisují typ a atributy požadovaných a přenášených dat (na rozdíl od SMTP data na plných 8 bitů). RFC 1945
HTTP v1.1více hlaviček umožňujících např. řízení cache, persistentní spojení, atd. Povinná hlavička Host pro podporu virtuálních serverů. RFC 2068
Komunikace v protokolu HTTP v1.x probíhá takto (v v0.9 je pouze dotaz GET [url] a jako odpověď jen samotná data):
klient → server:
[metoda] [url] HTTP/1.x
[hlavičky]
[\n]
[data dotazu]
server → klient:
HTTP/1.x [návratový kód] [popis kódu]
[hlavičky]
[\n]
[data odpovědi]
Metody HTTP v1.0 mohou být:
GETslouží k získání daného dokumentu ze serveru
POSTslouží k odeslání dat v dotazu (např. formulářových dat)
HEADfunguje podobně jako GET, ale v odpovědi pošle server pouze hlavičky (používá se např. pro zjištění času poslední modifikace dokumentu).
HTTP v1.1 přidává i několik nových metod:
PUTslouží k uložení zaslaného objektu na dané URL
DELETEodstranění objektu daného URL ze serveru
TRACEzjišťování spojení, vrací odpověd bez dat
CONNECTnastavení způsobu spojení
OPTIONSzjišťování možností spojení
Hlavičky slouží pro přenos ruzných doplňujících informací. Každá hlavička je na samostatné řádce a má tvar [jméno hlavčky]: [hodnota]. Příklady hlaviček v protokolu HTTP v1.1:
Hostv dotazu udává plné doménové jméno virtuálního web–serveru
Content-Typev odpovědi udává MINE typ obsahu datové části
Content-Lengthv odpovědi udává délku datové částit
Content-Encodingv odopovědi udává kódování datové části (např. komprimované data v kódování gzip)
Accept, Accept-Charset,
Accept-Encoding, Accept-Language
v dotazu říká klient serveru, které typy dokumentů, kódování znaků, kódování obsahu a jazyk dokumentů je schopen akceptovat (vždy více možností s udáním priorit)
Server vrací na každý dotaz protokolu HTTP v1.x návratový kód:
1xx -- informační kódy (nepoužívá se)
2xx -- úspěšné vyřízení požadavku
200 okpožadavek byl úspěšně zpracován
201 createdvýsledkem požadavku je nově vytvořený objekt
200 acceptedpožadavek byl přijat, ale dosud není zpracován
200 no contentpožadavek byl úspěšně zpracován, ale jeho výsledkem nejsou žádná data pro klienta
3xx -- přesměrování
301 moved permanentlypožadovaný objekt byl trvale přemístěn na jinou adresu
302 moved temporarilypožadovaný objekt byl dočasně přemístěn na jinou adresu
304 not modifiedobjekt nebyl změněn (odpověď při podmíněném požadavku pomocí hlavičky if-modified-since)
4xx -- chyba klienta
400 bad requestšpatná syntaxe dotazu
401 unauthorizedobjekt je dostupný pouze po autorizaci
403 forbiddenpožadavek je v pořádku, ale server nemá povoleno jej vykonat
404 not foundpožadovaný objekt nebyl na serveru nalezen
5xx -- chyba na straně serveru
500 internal server errorserveru se něco stalo a nemůže vyplnit požadavek
501 not implementedserver nepodporuje metodu uvedenou v požadavku
502 bad gatewayserver, pracující jako gateway, dostal špatnou odpověď od dalšího serveru
503 service unavailableslužba je nedostupná (přetížení, údržba serveru)

Adresování dokumentů

Pomocí Uniform Resource Locator (URL) lze jednoznačně popsat umístění objektu na síti Internet. Tvar URL je:
[schéma]://[uživatel]:[heslo]@[server]:[port]/[umístení]
Pokud označuje umístění pouze adresář na serveru (ne soubor) mělo by vždy končit znakem lomítko. Mnohé servery však URL s chybějícím lomítkem sami doplní na celé správné URL. V odkazech se často používají relativní URL. Taková URL musí být před tvorbou HTTP dotazu převedeny na absolutní.

Jazyk (X)HTML

Většina dokumentů, které tvoří Web, jsou zapsané v jazyce HyperText Markup Language (HTML). Klient musí po přijetí takových dat dokument zformátovat a zobrazit uživateli. V současné době je jazyk HTML nahrazován jeho novější formou – jazykem XHTML založeném na standardu XML (HTML je „pouze“ SGML).
Jazyk (X)HTML nabízí také jistý ekvivalent k hlavičkám HTTP protokolu. Jedná se o META tagy, v části html/head, formátu:
<meta http-equiv="[název hlavičky]" content="[hodnota hlavičky]">
Tyto pseudo-hlavičky jsou vyhodnoceny prohlížečem a měly by mít nižší prioritu než pravé hlavičky HTTP protokolu. Používají se zejména pro uložení jazyka a znakové sady dokumentu, protože pak je tato informace přístupná i v off-line verzi uloženého dokumentu. Např. <meta http-equiv="Content-Type" content="text/html; charset=windows-1250">

Příklad

$ telnet aisa 80
Trying 147.251.48.1...
Connected to aisa.fi.muni.cz.
Escape character is '^]'.
GET / HTTP/1.1
Host: www.fi.muni.cz
Accept: text/html
Accept-Language: cs
Accept-Charset: iso-8859-2


HTTP/1.1 200 OK
Date: Fri, 12 Nov 2004 13:59:59 GMT
Server: Apache/1.3.29 (Unix) mod_ssl/2.8.16 OpenSSL/0.9.7d
Content-Location: index.cgi
Vary: negotiate,accept-charset
TCN: choice
Transfer-Encoding: chunked
Content-Type: text/html; charset=ISO-8859-2

7e7
<!-- begin include -->

<!-- begin include -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
…

HTTP server Apache

Nejrozšířenějším webovým serverem je HTTP server Apache společnosti Apache Software Foundation. Původní server byl založen na opatchovaném serveru NCSA (odtud také název apache = a patche) a vznikl v roce 1995, jako verze 0.2. Nyní je server Apache již ve verzi 2.0.52 (souběžně se vyvíjí verze 1.3.x, aktuální je 1.3.33).

Moduly

Server se skládá z jádra http_core a modulů, které mohou být buď přilinkovány po kompilaci nebo nahrávány dle potřeby při startu serveru (DSO – Dynamic Shared Objects). Díky snadnému přidávání modulů a známému rozhraní (celý server je open source, zdarma) existuje velké množství modulů používajících různé knihovny třetích stran.
Příklady některých modulů:
mod_sopodpora pro moduly DSO (musí být přilinkován pokud bude server načítat DSO moduly)
mod_accesřízení přístupu na základě doménového jména nebo IP-adresy
mod_authautentizace uživatelů (viz. dále)
mod_statuszpřístupnění statistik serveru na sepciálním URL
mod_infozpřístupnění výpisu konfigurace na sepciálním URL
mod_auth_ldapautentizace uživatelů pomocí LDAP
mod_sslumožňující použití SSL a TLS (viz. dále)
mod_mime_magicnastavení MIME typu souboru na základě obsahu souboru (jako file)
mod_negotiationvyhodnocení obsahu dokumentu na základě nastavení prohlížeče
mod_includepoužití serverem vkládaných vsuvek (SSI)
mod_czechkonverze mezi různými českými znakovými sadami
mod_cgizajišťuje spouštění CGI skriptů (viz. dále)
mod_userdirumožňuje prezentovat webové strákny uživatelů z ~/public_html/
mod_perl, mod_phppodpora iterpretů jazyků přímo do serveru (nevolá se jako CGI)
mod_proxypodpora pro proxy přístupy
mod_rewritepodpora přepisování URI

Kompilace

Stáhneme zdrojové kódy serveru z Apache Software Foundation, rozbalíme a přesunem se do adresáře. Spustíme:
$ ./configure --prefix=[kam instalovat] --enable-module=most --enable-shared=max
$ echo "teď máme nakonfigurován překlad pro náš OS a knihovny"
$ make all install
$ echo "nyní je server přeložen, slinkován a nainstalován"
$ [kam instalovat]/bin/apachectl start
$ echo "a teď už běží"
Tím se přeloží většina používaných modulů a skoro všechny se zkompilují jako DSO moduly. Příslušné parametry můžeme samozřejmě nahradit vlastním výběrem modulů. Před zkonfigurováním překladu (příkaz configure) je dobré nainstalovat příslušné knihovny (např. PHP, OpenSSL, …), případně parametry zadat cestu k těmto knihovnám.
Pozdější přidání modulu (jako DSO) zajistí:
$ ./configure --prefix=[kam instalovat] --add-module=[cesta k modulu] --enable-shared=[modul]

Instalace

Pokud jsme kompilovali Apache podle předchozího kroku, máme ho již nainstalovaný. V opačném případě si stáhneme balíček Apache-… z naší oblíbené distribuce Linuxu a nainstalujem. Případně ještě spustíme: /etc/init.d/httpd start
Přestože se v dokumentaci doporučuje trvalý běh serveru, můžeme ho také spouštět jen pomocí inetd, potom bude v /etc/inetd.conf následující:
www stream tcp nowait root /usr/sbin/httpd httpd -f /etc/httpd/conf/httpd.conf
Při spouštění pomocí inetd se musí také upravit konfigurační soubor httpd.conf, nastavit ServerType inetd

Konfigurace

Konfigurační soubory serveru jsou standardně uloženy v adresáři /etc/httpd.
httpd.confzákladní charakteristiky serveru, jeho startu a prostředí, cesty k dalším souborům
srm.conflogické chování serveru
access.confřízení přístupu k serveru
magic.confdefinice chrakteristik souborů a jim odpovídajícím MIME typům, nedoporučuje se upravovat
U posledních verzí serveru je konfigurace většinou pouze (pomineme-li zvláštní konfigurační soubory) v souboru httpd.conf. Přesto doporučuji vytvořit více konfiguračních souborů (např. pro virtuální hosty, SSL) a do httpd.conf je naincludovat – je to přehlednější.
Chování serveru v konkrétních adresářích (lokální chování) lze dodatečně nastavit (pokud je to povoleno v httpd.conf) soubory .htaccess a .htpasswd (umístěné v adresáři jehož publikaci mají ovlivňovat). Často se používají k řízení přístupu k určitým adresářům či souborům.
Konfigurační diriktivy jsou rozděleny do tří sekcí:
  1. diriktivy definující chování procesu serveru a prostředí,
  2. direktivy definující parametry hlavního serveru, jehož požadavky nejsou odchytávány virtuálními servery, a defaultní hodnoty pro virtuální servery,
  3. nastavení virtuálních hostů (viz. dále).
Direktivy mohou být umístěny v podmíněných sekcích <IfModule [modul]>…</IfModule> a <IfDefine [přepínač]>…</IfDefine> nebo v sekcích udávající objekt, jehož vlastnosti nastavují (např. <Directory [fyz. adresář]>, <Location [web. adresář]>). Některé direktivy:
ServerRoot [adresář]kořenový adresář web-serveru Apache
KeepAlive [On|Off]povolí persistentní spojení (viz. HTTP v1.1)
StartServers [číslo]min. počet běžících dětí serveru (regulace zátěže)
Listen [adresa]:[port]kde má server poslouchat
LoadModule [cesta k modulu]načtení DSO modulů
User [už.], Group [sk.]účet, kde má běžet server (např. ftp), ne root!
DocumentRoot [adresář]kde je kořen. adr. přístupných dokumentů web-serveru
DirectoryIndex [soubory]jaké soubory zobrazit při přístupu k adresáři (/) místo výpisu obsahu adresáře

CGI skripty

Common Gateway Interface (CGI) skripty umožňují dynamicky generovat obsah dokumentů přistupovaných pomocí web-serveru. CGI jsou programy, které se při přístupu (pomocí URL) spouští na straně serveru v serverem definovaném prostředí a se vstupem dat dotazu. Jejich výstup je poté předáván klientovi.
Pro možnost spouštění CGI musíme zavést (nebo přilinkovat) modul mod_cgi a nastavit direktivy v httpd.conf:
AddType application/x-httpd-cgi .cgi
<Directory [fyz. adresář kde mohou být spouštěny CGI skripty]>
  Options ExecCGI
</Directory>
ScriptAlias [web. adresář] [fyz. adresář se skripty]   # pro globálně přístupné CGI skripty
Poslední direktiva říká, že ve web. adresáři [web. adresář] na kterémkoli serveru (např. virtuálním serveru), budou umístěny jen CGI skripty nacházející se v adresáři [fyz. adresář se skripty]. Používá se pro umístění globálně přístupných CGI skriptů (např. počítadlo přístupů) a jejich oddělení od definice struktury stromu publikovaných dokumentů.
Pokud chceme na používat PHP skripty, máme dvě možnosti. Buď se používá PHP jako interpret skriptů a PHP skripty jsou obyčejné CGI skripty s interpretem PHP (na prvním řídku mají #!/cesta/k/php). Nebo použijeme modul php4_module. Pro modul stáhneme distribuci PHP z www.php.net a v adresáři distribuce provedeme:
$ ./configure --with-apxs2=[kořenový adresář Apache]/bin/apxs [další volby, např. další moduly]
$ make all install
A upravíme httpd.conf
LoadModule php4_module modules/libphp4.so
AddType application/x-httpd-php .php   # pro interpretaci PHP skriptů
AddType application/x-httpd-php-source .phps   # pro syntax-highlighting zdrojáků PHP skriptů
Musíme také nakonfigurovat samotné PHP. Upravíme tedy soubor php.ini v adresáři, odkud načítá PHP konfiguraci (obvykle /etc/php.ini nebo, který jsme zvolili při konfiguraci volbou --with-config-file-path).

Zpřístupnění dokumentu ve více jazycích

Při dotazu na server může klient specifikovat, jakou podporuje znakovou sadu a jazyk dokumentů včetně kombinací a priorit možností (viz. hlavičky HTTP). Tento údaj může využít server pro výběr vhodného dokumentu (případně pro jeho úpravu).
Apache umožňuje zvolit reprezentaci dokumentů na základě údajů:
Acceptpreferovaný typ média
Accept-Languagepreferovaný typ jazyka
Accept-Charsetpreferovaná znaková sada (možno už v Accept)
Accept-Encodingpreferované kódování
Pro výběr vhodného dokumentu může serever využít dvě metody.

Čeština

Zpřístupnění dokumentů ve více znakových sadách by se jistě dalo dělat pomocí MultiViews nebo typových map (viz. předchozí kapitola), ale to by vyžadovalo jeden dokument pro jednu znakovou sadu. Proto je lepší vytvořit jednu verzi dokumentu a tu překódovávat dle požadavků klienta. To umožňují např. WWWdia pana J.Košťála, SaCzech od pana Pavla Satrapy, CSáček od pana Jaromíra Dolečka (z FI), mod_czech od InterSoftu a mod_html od pana Lampy.
WWWdia detekuje výběr znakové sady podle řetězce ?__CHARSET__ na konci odkazu. To přináší nevýhodu, že umí překódovat jen statické stránky (nedá se tedy použít pro překódování například výstupu různých CGI skriptů). SaCzech nemá nevýhody předchozího produktu, ale je napsán v Perlu a odezva s použitím překódování je výrazně horší než bez něj.
Mod_czech a mod_html jsou (na rozdíl od předchozích produktů) moduly DSO, což zrychluje jejich práci (běží v procesu serveru), ale bohužel vyžadují opatchování zdrojáků serveru a jeho rekompilaci.
CSáček může běžet jako CGI, FastCGI i jako modul DSO a neměl by vyžadovat žádné dodatečné úpravy ve zdrojácích serveru (snad jen malou změnu u Apache-SSL), bohužel pod mod_ssl nebyl testován a tedy nefunguje. Potřebné podpora bude do CSáčku přidána v nejbližší verzi, tj. v některé z řady 2.1.X.
Konkrétní postup kompilace a instalace uvedených produktů můžete nalézt na jejich webových stránkách.

Virtuální servery

Virtuální server je web-server provozovaný společně s ostatními virtuálními web-servery na jednom (nevituálním) serveru, tj. na jednom HW a hlavně jednom SW. Virtuální server může být rozlišen dvěma způsoby:
  1. IP-adresou – každý virtuální server má vlastní IP adresu. Podporované i staršími verzemi Apache, problém je sehnat více IP adres pro jeden počítač. Moderní jádra umožňují přiřadit jednomu síťovému interface více IP adres (např. ifconfig eth1:1 10.0.30.10; ifconfig eth1:2 10.0.30.11).
    Pak konfigurujem IP-based virtuální servery v httpd.conf:
    <VirtualHost domenove-jmeno-1-ip>
      ServerName domenove-jmeno-1-ip
      ServerAlias www.domenove-jmeno-1-ip
      DocumentRoot /home/httpd/html/virtual/domenove-jmeno-1-ip
    <VirtualHost>
  2. doménovým jménem – každý virtuální server má vlastní doménové jméno (např. pomocí CNAME záznamů), ale mají jednu společnou IP adresu. Tento způsob je poměrně jednoduchý na správu a konfiguraci, ale jak si později ukážem, má některé nevýhody. Používá se hlavně pro virtuální servery na doménách třetí úrovně.
    Pak konfigurujem name-based virtuální servery v httpd.conf:
    NameVirtualHost [IP adresa rozhraní]   # uvádí se pouze jednou !!!
    <VirtualHost [IP adresa rozhraní]>
      ServerName domenove-jmeno
      ServerAlias www.domenove-jmeno
      DocumentRoot /home/httpd/html/virtual/domenove-jmeno
    <VirtualHost>
Můžeme také vytvořit více serverů (běžících programů serveru) naslouchající na různých adresách či portech. To ale nejsou virtuální servery (pokud samozřejmě není na jednom z nich více virtuálních serverů).

SSL

SSL/TLS je síťový protokol mezi transportní a aplikační vrstvou ISO OSI modelu. Zajišťuje autentizaci serveru, volitelnou autentizaci klienta, integritu, autentizaci původu a důvěrnost přenášených dat (včetně jejich komprese). SSL pracuje na bázi asymetrické kryptografie (pro autentizaci a ustanovení sdíleného klíče relace) a symetrické kryptografie (pro přenášení dat v rámci relace). Server (volitelně klient) má jeden pár (soukromý,veřejný) klíč. V následujícím popisu budeme používat OpenSSL a Mod_SSL.
Stáhneme zdrojové kódy OpenSSL např. z ftp://ftp.openssl.org/source/, přeložíme a nainstalujem (./config; make all install) nebo rovnou nainstalujem balíček z naší oblíbené distribuce Linuxu. Stáhneme zdrojové kódy Mod_SSL např. z ftp://ftp.modssl.org/source/, případně stáhneme zdrojáky Apache s Mod_SSL, přeložíme s parametry adresáře Apahce a OpenSSL (./configure --with-apache=... --with-ssl=... --prefix=[cesta k zdrojaku Apache]; cd [cesta k zdrojakum Apache]; make all install nebo cd [cesta k zdrojakum Apache]; ./configure --enable-mods-shared=ssl --with-ssl=[cesta k OpenSSL] pokud je mod_ssl již součástí Apache).
Nyní vygenerujem certifikáty serveru (pro náš účel budou stačit testovací certifikáty bez certifikační autority, podepsané samy sebou):
openssl genrsa -out nas_server.key 1024
openssl req -new -x509 -key nas_server.key -out nas_server.crt -days [platnost dnů]
Atribut CN (CommonName) by měl být shodný s plným doménovým jménem našeho HTTPS serveru. Soubor nas_server.crt obsahuje veřejný certifikát a soubor nas_server.key obsahuje soukromý klíč.
Konfigurace SSL se provádí v httpd.conf, případně v naincludovaném ssl.conf a obsahuje definici virtuálního serveru, který bude podporovat HTTPS (tento server musí být jediný nebo IP-based, viz. dále). Důležité jsou direktivy:
SSLCertificateFileveřejný certifikát serveru
SSLCertificateKeyFilesoukromý klíč serveru
SSLEngine [On|Off]povoluje SSL
Apache se SSL se pak spuští příkazem: apachectl startssl. Pokud je soukromý klíč chráněn heslem (volba -des3 při openssl genrsa) bude Apache vyžadovat při startu zadání tohoto hesla.
SSL nelze použít u name-based virtuální serverů. Vrstva protokolu SSL je umístěna pod vrstvou protokolu HTTP a je vlastně jeho obálkou. Když je vytvořeno SSL spojení (HTTPS), Apache, resp. mod_ssl musí se vzdálenou stranou (klientem) vyjednat parametry SSL spojení (musí zjistit typ použitého šifrování, certifikát serveru apod.). Apache naproti tomu nemůže bez HTTP hlavičky Host delegovat dotaz na správný webový server, protože to je možné pouze po načtení této hlavičky od klienta. Jenže aby přišla od klienta nějaká data, musí být dokončeno vyjednávání parametrů SSL spojení. A to je spor :-)

Autentizace HTTP spojení

Protože protokol HTTP je bezstavový protokol, autentizace přes obyčejné HTTP (bez použití SSL) je obtížná (zapamatovat si, že uživatel byl autentizován, je změna stavu). Proto se musí v každém HTTP spojení posílat nějaký příznak, že je uživatel autentizován (případně ho vždy autentizovat znova).
Protokol HTTP nabízí serveru Basic autentizaci pro autentizaci klienta hlavičku WWW-Authenticate: Basic realm="[jméno realmu]" a stavový kód HTTP/1.0 401 Unauthorized. Pokud klient přijme uvedenou hlavičku a kód, měl by si vyžádat od uživatele autentizaci. Takto to musí probíhat při každém spojení klienta na server (nicméně klient si může login a heslo pamatovat a příště ho poslat již bez účasti uživatele).
Mezi další oblíbené způsoby autentizace (využívající jiných neautentizačních možností protokolu HTTP) patří např. autentizace pomocí otevřených cookies, pomocí identifikátoru spojení v cookies, pomocí IP adresy, pomocí identifikátoru spojení založeného na IP adrese, pomocí identifikátoru v nestandarních hlavičkách, pomocí challenge-response za podpory prohlížeče, pomocí Javy v prohlížeči, atd.

Alternativní HTTP servery

Podle výzkumu na http://www.netcraft.co.uk/Survey/ je Apache nejrozšířenější server v síti Internet. Přesto například při použití webových technologií založených na jazyku Java není Apache použitelný. Apache TomCat?
Mezi úspěšné komerční webové servery patří IIS od Microsoftu (což pro nás asi nemá smysl :-) nebo webový server Zeus.
Zajímavé jsou také servery kombinující kalsický webový modulární server (jako je Apache) s plně javovým serverem (na platformě nezávislý server umožňující spouštění JavaServletů). Mezi jejich zástupce patří např. webový server Jetty://. Javové servlety zvládá také web-server Roxen pod licencí GPL.
Zajímavou možností je také provozovat webový server jako součást jádra OS Linux. kHTTPD je HTTP démon zakompilovaný jako modul do linuxové jádra. Umožňuje publikovat statické objekty (vpodstatě jen soubory), přičemž dynamické stránky umí přesměrovat na jiný webový server (např. Apache). Díky umístění v jádře operačního systému má webový server kHTTPD vynikající odezvu a zvládá velkou zátěž.

Odkazy