kategória | ||||||||||
|
||||||||||
|
||
Egyszerű web szerver készítése
Alkalmazási réteg vizsgálata
A World Wide Web napjaink leggyakrabban használt internetes szolgáltatása, amely kommunikációjához a HTTP (HyperText Transfer Protocol)-t használja. Ez a protokoll lehetővé teszi, hogy a HTTP kliensek, vagyis a böngészők letöltsenek oldalakat, képeket és egyéb állományokat a HTTP, vagyis web szerverekről.
Amikor a böngészővel (Firefox, In 353f51d ternet Explorer, Lynx, stb.) le akarunk tölteni egy oldalt, akkor a következő folyamatok játszódnak le:
Mint az előzőekből kiderült, több verziója is létezik a protokollnak. Az 1.0 verziótól kezdődően a verzió száma szerepel a kérés és a válasz fejlécében. Lehetőség van arra, hogy a különböző verziójú böngészők, proxyk, és szerverek is együtt működjenek. Ez úgy valósulhat meg, hogy mindegyik eszköz támogatja visszamenőlegesen a korábbi verziókat. A közös HTTP verzióban, illetve opciókban az egyes eszközök úgy állapodnak meg, hogy a kérés és válasz átvitele során a saját képességeiknek megfelelően csökkentik a kommunikációs szintet. Vagyis a gyakorlatban a kommunikációban résztvevő elemek megállapodnak a legnagyobb olyan HTTP verzióban, amelyet mindannyian támogatnak.
Ez a mechanizmus lehetővé teszi számunkra, hogy a már elavultnak számító HTTP 1.0 protokollt használjuk a szerverünkben, mert a legújabb böngészők is támogatni fogják.
A HTTP protokollban a kérések általános formája a következő:
parancs URL protokoll-ID<CR><LF>
fejléc<CR><LF>
<CR><LF>
test
A parancs mező a kliens kérésének szöveges parancsát tartalmazza. Az URL (Uniform Resource Locator) a dokumentum címét jelenti. Ez megegyezik azzal a szöveggel, amit a böngészők címsorába beírunk. A protokoll-ID a használt HTTP verzió azonosítóját tartalmazza. Esetünkben ez a "HTTP/1.0" szöveget jelenti. A fejléc rész további információkat, bővítéseket tartalmazhat, amelyet a kliens csatol a kéréshez. A kérés test része az adatküldésnél használatos, és a böngésző által küldött adatokat tartalmazza.
A szerver által küldött válaszok általános alakja:
protokoll-ID hibakód üzenet<CR><LF>
fejléc<CR><LF>
<CR><LF>
test
A protokoll-ID hasonlóan a kéréshez a használt HTTP protokoll azonosítója. A szerver által támogatott verzió kerül ide. A hibakód a szerver programok által értelmezhető válaszkódját tartalmazza. Az üzenet a hiba szöveges leírása, amelyeta böngészők nem értelmeznek. A fejléc rész további információkat tartalmaz a válasz üzenethez. Tipikusan a dokumentum típusát, méretét, utolsó módosítását, gyorsító tárban való tárolhatóságát tartalmazza. A válasz test része hordozza magát a dokumentumot, amely lehet egy HTML oldal, kép, videó, vagy egyéb állomány.
A HTTP 1.0 verzióban a kliens 3 kérés típust küldhet a szervernek.
A HEAD parancs arra kéri a szervert, hogy a megnevezett dokumentum fejlécét küldje vissza. A szerver által visszaküldött fejlécnek minimum tartalmaznia kell a dokumentum hosszát, az utolsó módosítás dátumát, és a típusát.
Példa:
HEAD /htdocs/index.html HTTP/1.0
A GET parancs arra kéri a szervert, hogy a megnevezett dokumentumot keresse meg és küldje vissza. A szerver visszaküldi a HEAD-nél is visszaadott fejlécet, és ezt követi a dokumentum. A GET parancs arra is használható, hogy információkat küldjön vissza a szerver számára, azonban erre a feladatra elsősorban a POST parancs szolgál.
Példa:
GET /htdocs/index.html HTTP/1.0
A POST parancs arra szolgál, hogy adatokat küldjünk vele a klienstől a szervernek. Leggyakrabban a HTML formok használják ezt a metódust az adatok elküldésére. Természetesen a kérés a parancson kívül tartalmaz egy fejlécet minimum az adatokat tartalmazó test hosszával, és a test részben az adatokat.
Példa:
POST /htdocs/forms/question.html HTTP/1.0
Content-length: 6
data=5
A szerverek leggyakrabban használt hibakódjait a következő táblázat foglalja össze.
Hibakód |
Üzenet |
Értelmezés |
|
Ok |
Minden rendben. A válasz test része tartalmazza a dokumentumot. |
|
Redirect |
A szerver átirányítja a klienst egy másik oldalra. |
|
Access denied |
A szerver jogosultsági okból megtagadja a dokumentum letöltését. |
|
Not found |
A dokumentum nem található. |
|
Server error |
A szervernek problémája van a kérés kiszolgálásával. |
A HTTP protokoll működése során a felépített TCP/IP csatornán szövegesen küldi át azokat az üzeneteket, amelyeket az előző fejezetekben tárgyaltunk. Ezen tulajdonsága lehetővé teszi, hogy akár manuálisan is kipróbálhassuk a működését a telnet program segítségével.
Először is nézzünk meg egy egyszerű kommunikációt a kliens és a szerver között!
Kliens |
GET / HTTP/1.0 |
Szerver |
HTTP/1.0 200 OK Content-Length: 52 Content-Type: text/html <HTML> <HEAD>Teszt</HEAD> <BODY>Teszt</BODY> </HTML> |
Nézzük ezt meg egy hiba esetén, amikor a szerver nem találja a dokumentumot!
Kliens |
GET /valami.html HTTP/1.0 |
Szerver |
HTTP/1.0 404 Not Found Content-Length: 94 Content-Type: text/html <HTML> <HEAD>404 Not Found</HEAD> <BODY>A kért oldal nem található a szerveren.</BODY> </HTML> |
A telnet program segítségével ezt ki is próbálhatjuk. A telnet programot promptból indíthatjuk. Windows alatt a cmd.exe, Linux alatt egy terminál teszi ezt lehetővé. Feladatunk, hogy kapcsolódjunk egy web szerver 80-as portjához, amelyet a következő paranccsal végezhetünk el:
telnet szerver.hu 80
Mivel a protokolban nincs üdvözlés, ezért a kapcsolat létrejötte után semmilyen üzenetet nem láthatunk a szervertől. Mivel most mi egy HTTP klienst szimulálunk, ezért be kell írnunk egy HTTP protokoll szerinti kérést. Az egyszerűség kedvéért írjuk be a következő sort és nyomjunk utána két Entert.
GET / HTTP/1.0
Ez a kérés lekéri a szerver fő oldalát HTTP/1.0 protokollal. Bizonyos telnet implementációk esetén (pl. Windows) nem látható, amit begépelünk ilyenkor, csak a szerver válasza. Vagyis ebben az esetben vakon kell begépelni a szöveget.
A kérés beírása után a szerver válaszát azonnal láthatjuk. Mivel a HTML oldal valószínűleg hosszú, ezért vissza kell görgetnünk a szöveget, hogy a szerver hibakódját és a fejléc tartalmát is megvizsgálhassuk.
A gyakorlat során a hallgató feladata, hogy elkészítsen egy egyszerű, a HTTP 1.0 protokollt megvalósító web szervert C nyelven. Ennek a következőket kell teljesítenie:
Egy paraméterként megadott TCP porton fogadja a böngészők kapcsolódásait!
Egyszerre elegendő, ha csak egy böngészőt szolgál ki.
Elegendő csak a GET műveletet implementálni. A többi műveletre adjon 500-as hibát.
A GET parancsban érkező dokumentum megnevezést ki kell olvasni és a hivatkozott dokumentumot el kell küldeni a válaszcsomagban a kliens felé!
Amennyiben a hivatkozott dokumentum nem létezik, adjon 404-es hibát.
A válasz elküldése után bontsa a kapcsolatot és fogadja a következő böngésző kapcsolódást!
A teszteléshez létre kell hozni egy egyszerű HTML állományt! (lásd: protokoll példa)
A feladat megvalósításához kiindulási pontnak használható a "TCP szerver készítése" gyakorlaton megvalósított szerver program, így ezt a hallgatónak célszerű magával hoznia!
A Web szerver implementációjához a szerver programnak a kommunikáció részét kell módosítania. A klienstől, vagyis a böngészőtől kapott csomagot be kell olvasni és string kezelő függvényekkel (pl. sscanf()) kinyerni belőle a kérés típusát és a kért állomány nevét.
Ha a kérés nem értelmezhető, vagyis nem GET parancs érkezik benne, akkor a 500-as hibakóddal egy hibaüzenetet kell összeállítani és elküldeni.
Ha a dokumentum nem megnyitható, akkor 404-es hibakóddal egy hibaüzenet kell összeállítani és visszaküldeni.
Ha sikerül megnyitni a dokumentumot, akkor a protokoll példában is látható módon egy válasz üzenetet kell összeállítani, és a dokumentummal együtt elküldeni.
Minden esetben a válasz után a kapcsolatot bontani kell és új kapcsolódásokra várakozni.
Az egyes rendszerhívásokról és C függvényekről a man parancs segítségével angol nyelvű segítséget érhetünk el. Ennek formája:
Rendszerhívások esetén:
man 2 rendszerhívás
C függvények esetén:
man 3 C-függvény
Az elkészült forráskódot a gcc parancs segítségével fordíthatjuk le. Ennek paraméterezése a következő:
gcc -Wall -o kimenet forrás.c
A fordító sikeres fordítás esetén nem ír ki semmit, csak előállítja a futtatható program kódot. Probléma esetén a problémákat három csoportra oszthatjuk:
Típus |
Leírás |
Figyelmeztetés (warning) |
A jelzett sor szintaktikailag nem hibás, de érdemes ellenőrizni, mert elvi hibás lehet. Viszont a program lefordul és használható. |
Fordítási hiba (compiler error) |
A jelzett sor szintaktikailag hibás, vagy valamely korábbi sorban elkövetett hiba hatása. |
Linker hiba (linker error) |
A linker nem találja a hivatkozott kódot. Többnyire függvény név elírások okozzák. |
A lefordított programot a következő módon lehet futtatni:
./program param1
Ez az aktuális könyvtárból lefuttatja a program nevű programot a param1 paraméterrel. A programot leállítani a Ctrl+C billentyű kombinációval lehet.
Az elkészült web szervert kipróbálhatjuk telnet program segítségével a fejlesztési fázisban, hogy megvizsgáljuk a kommunikáció helyességét. Az elkészült programot végül célszerű egy böngészővel tesztelni (pl.: firefox). A böngészőt megnyitva a címsorába a következőt kell írnunk (ha lokálisan próbáljuk, a használt port 1234, és a html állomány neve proba.html):
https://localhost:1234/proba.html
Ennek hatására meg kell, hogy jelenjen a html állomány tartalma.
:
2038