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.9 | pouze 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.0 | formá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.1 | ví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:
GET | slouží k získání daného dokumentu ze serveru |
POST | slouží k odeslání dat v dotazu (např. formulářových dat) |
HEAD | funguje 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:
PUT | slouží k uložení zaslaného objektu na dané URL |
DELETE | odstranění objektu daného URL ze serveru |
TRACE | zjišťování spojení, vrací odpověd bez dat |
CONNECT | nastavení způsobu spojení |
OPTIONS | zjišť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:
Host | v dotazu udává plné doménové jméno virtuálního web–serveru |
Content-Type | v odpovědi udává MINE typ obsahu datové části |
Content-Length | v odpovědi udává délku datové částit |
Content-Encoding | v 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 ok | požadavek byl úspěšně zpracován |
201 created | výsledkem požadavku je nově vytvořený objekt |
200 accepted | požadavek byl přijat, ale dosud není zpracován |
200 no content | požadavek byl úspěšně zpracován, ale jeho výsledkem nejsou žádná data pro klienta |
3xx -- přesměrování |
301 moved permanently | požadovaný objekt byl trvale přemístěn na jinou adresu |
302 moved temporarily | požadovaný objekt byl dočasně přemístěn na jinou adresu |
304 not modified | objekt 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 unauthorized | objekt je dostupný pouze po autorizaci |
403 forbidden | požadavek je v pořádku, ale server nemá povoleno jej vykonat |
404 not found | požadovaný objekt nebyl na serveru nalezen |
5xx -- chyba na straně serveru |
500 internal server error | serveru se něco stalo a nemůže vyplnit požadavek |
501 not implemented | server nepodporuje metodu uvedenou v požadavku |
502 bad gateway | server, pracující jako gateway, dostal špatnou odpověď od dalšího serveru |
503 service unavailable | služ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_so | podpora 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_auth | autentizace uživatelů (viz. dále) |
mod_status | zpřístupnění statistik serveru na sepciálním URL |
mod_info | zpřístupnění výpisu konfigurace na sepciálním URL |
mod_auth_ldap | autentizace uživatelů pomocí LDAP |
mod_ssl | umožňující použití SSL a TLS (viz. dále) |
mod_mime_magic | nastavení MIME typu souboru na základě obsahu souboru (jako file ) |
mod_negotiation | vyhodnocení obsahu dokumentu na základě nastavení prohlížeče |
mod_include | použití serverem vkládaných vsuvek (SSI) |
mod_czech | konverze mezi různými českými znakovými sadami |
mod_cgi | zajišťuje spouštění CGI skriptů (viz. dále) |
mod_userdir | umožňuje prezentovat webové strákny uživatelů z ~/public_html/ |
mod_perl, mod_php | podpora iterpretů jazyků přímo do serveru (nevolá se jako CGI) |
mod_proxy | podpora pro proxy přístupy |
mod_rewrite | podpora 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.conf | základní charakteristiky serveru, jeho startu a prostředí, cesty k dalším souborům |
srm.conf | logické chování serveru |
access.conf | řízení přístupu k serveru |
magic.conf | definice 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í:
- diriktivy definující chování procesu serveru a prostředí,
- 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,
- 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ů:
Accept | preferovaný typ média |
Accept-Language | preferovaný typ jazyka |
Accept-Charset | preferovaná znaková sada (možno už v Accept) |
Accept-Encoding | preferované 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:
- 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>
- 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:
SSLCertificateFile | veřejný certifikát serveru |
SSLCertificateKeyFile | soukromý 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