Vorgurakendused 2 prax 1 2016
Ülesandeks on implementeerida lihtne P2P protokoll anonüümseks HTTP päringute tegemiseks.
- realiseeritud HTTP protokolli peale (vaja implementeerida ka HTTP server ja klient)
- hakkab tööle virtuaalses võrgus (tehtud kohaliku startupi https://rangeforce.com/ poolt)
- eesmärk kõigi rakendused omavahel suhtlema ja ühise võrguna tegutsema panna
Ettevalmistus
Vali arenduseks töövahend: virtuaallaboris on olemas Java (+maven) ning Python 3 tugi. Muud keeled (Haskell, C, Javascript, C#) eeldavad, et tudeng saab ise arenduskeskkonna tööle. Seda on kasulik kohe alguses testida. Virtuaalmasinas jookseb Ubuntu desktop 16.04.
Tee avalikku git SCM teenusesse uus repo. Sobivad teenused on http://gitlab.com, http://github.com, http://bitbucket.com .
Leia tehtud repo URI. Näiteks: git@gitlab.com:priitj/test3.git (SSH), https://gitlab.com/priitj/test3.git (HTTPS).
Üle SSH protokolli reposse pöördumiseks on vaja täiendavalt teha SSH võti. Selleks vaata juhendeid, näit. Githubi puhul https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/ ; https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/ (need juhendid sisaldavad ka konfi Windowsi/Linuxi/Maci git kliendi jaoks).
Töö käigus repo kasutamiseks on kaks alternatiivi:
- IDE-sse integreeritud giti klient. IntelliJ/PyCharm puhul tee uus projekt selliselt, et vali VCS->Checkout from Version Control->Git, pane URI (SSH või HTTPS oma) ning uus kataloog. Siis "Clone" ning edaspidi on projekti töökataloog juba seotud eelnevalt tehtud repoga.
- Käsurea git klient (GIT bash Windowsi all või git käsk Linuxi/Maci all). Sel puhul järgi Gitlabi/Githubi/Bitbucketi juhiseid repo kohalikku arvutisse kloonimiseks ning selle initsialiseerimiseks.
Virtuaallabor
HTTP server/klient
HTTP baasil töötav protokoll näeb välja umbes järgmine:
GET http://1.2.3.4/request?param1=val1¶m2=val2 POST http://1.2.3.5/response?param1=val1¶m3=val3
jne. Seega tuleb meil teha:
- HTTP server, mis suudaks vastu võtta GET ja POST päringut ning parseerida pathi ja parameetrid (query stringi). Meid huvitab ka IP, kust päring tuli, see tuleb edaspidi kasutamiseks meelde jätta. POST päringu puhul peab lugema päringu "keha" (body).
- Selle peale peaks serveris käivituma mingi funktsioon. Selle võime jätta hetkel tühjaks
- Lõpuks saadame vastuse samuti HTTP päringuga. Seega vaja selleks HTTP klienti.
Server tuleb realiseerida ise, kasutades võrgust leitavaid näiteid mikro-http-serveri jaoks (tüüpiliselt paar lehekülge koodi). Selliseid näitekoode võib täiesti otse kasutada.
C jaoks on sobiv mikroserver näiteks tiny, java jaoks sobib alustuseks sisseehitatud HTTP server. Socketi tasemel alternatiividest on see server väga hea väike näide, aga selgitava tekstita, ning selgitavate tekstidega servereid leiad mh siit ja siit.Loe java socketitest põhjalikumalt siit. Pythoni serverinäite saad siit; lühem ja uuem. Http kohta võib lugeda näiteks siit.
Rakendus: anonümiseeriv võrk
Eesmärgiks on ehitada anonümiseeriv võrk nagu Tor. Täpsemalt on eeskujuks praeguseks mitteaktiivne anonüümne failijagamise võrk MUTE Network. Sealt võetud ideid kasutades teeme võrgu, kus saab anonüümselt veebist faile (html vms) alla laadida.
Meie võrgus teab iga võrgusõlm (node) näiteks kolme naabrit. Kui sõlm A tahab alla laadida URL-i http://google.ee, saadab ta päringu kõigile oma naabritele. Need omakorda saadavad päringu oma naabritele jne. Päringul on kaasas salajane identifikaator - ainult A teab, et see identifikaator seostub temaga. Lõpuks jõutakse võrgusõlmeni B, kes otsustab, et laadib ise URL-i sisu alla. B ei tea kes URL-i sisu soovis, aga saadab vastuse suunas, kust ta päringu sai. Samal viisil liigub vastus mööda võrku tagasi, kuni jõuab A-ni, kes tunneb ära oma salajase identifikaatori.
Võrku liituda ja sealt lahkuda võib suvalisel ajal. Seetõttu tuleb liitudes ja edasi perioodiliselt värsket naabrite nimekirja küsida, selleks paigutatakse samasse võrgu eraldi kataloogiserver.
Protokoll
Port. Vaikimisi on eeldatud, et võrgusõlmed kasutavad sõnumite vastuvõtmiseks porti 1215. Kasuta seda, kui suhtled teiste üliõpilaste programmidega ja kataloogiserveriga virtuaallaboris. Iseseisvaks või kohalikuks testimiseks võib kasutada ka muid porte.
Päringu saamise kinnitus. Peale iga HTTP päringu saamist vastab võrgusõlm tekstiga "OK" juhul kui ei olnud viga ning tekstiga "Error: xxxxxxxxxxx" kui oli viga (xxxxxxxxxxx tähistab vabas vormis vea kirjeldust ning selle võib ka ära jätta). Vastuse saatmine on kohustuslik, isegi kui võrgusõlm päringuga tulnud sõnumit ignoreerib. Korrektse sõnumi puhul peab vastuse HTTP staatus olema 200, muul juhul on lubatud ka HTTP veakoodide esinemine.
URL-i (faili) alla laadimise päring
| nimi (path) | /download |
| parameetrid | ?id=xxxxxxxx&url=yyyyyyy |
| tüüp | HTTP GET |
| body |
xxxxxxxx on selle sõnumi jaoks genereeritud juhuslik number. Kui sama võrgusõlm näeb hiljem sama id-ga file sõnumit, siis see sisaldab soovitud vastust. yyyyyyy on täispikk URL, mis peab olema turvaliselt kodeeritud, Pythoni lahendus.
Näide: http://1.2.3.4:1215/download?id=7652354352&url=http%3A//google.ee/%3Fs%3Dbla%26lang%3Den
Käsitlemise reeglid:
- Kui sõlm algatab ise selle päringu, peab ta meelde jätma
id, et hiljem vastust ära tunda - Päringu algatav võrgusõlm saadab sõnumi kõigile hetkel teadaolevatele naabritele
- Esimest korda selle sõnumi vastu võtmisel otsustab võrgusõlm, kas faili alla laadida (tõenäosus x%, konfitav)
- Kui faili alla ei laadita, saadab võrgusõlm sõnumi edasi kõigile oma naabritele, v.a juhul kui naabri IP langeb kokku sõnumi edastanud sõlme IP-ga
- Kui fail alla laaditakse, siis algatatakse
filetüüpi sõnum (vt. allpool) - Mõlemal juhul tuleb meelde jätta sõnumi
idja edastanud võrgusõlme IP
- Teist korda sama (või enda algatatud)
id-ga sõnumi vastu võtmise korral seda ignoreeritakse - Päringu algatanud sõlm peab arvestama võimalusega, et võrgu ebastabiilse iseloomu tõttu ei ole vastuse saabumine garanteeritud
Faili sisu tagastamine
| nimi (path) | /file |
| parameetrid | ?id=xxxxxxxx |
| tüüp | HTTP POST |
| body | {"status":yyy, "mime-type":"zzzzzzzz", "content":"..."} |
xxxxxxxx on sama, mis download sõnumis, mille saamise tõttu fail alla laaditi. HTTP päringu kehas on JSON formaadis objekt, mis sisaldab base64 kodeeringus faili ja selle metadatat. yyy on faili allalaadimisel saadud HTTP staatus. zzzzzzzz on faili sisu MIME tüüp (peale dekodeerimist). "content" väljal on RFC-3548 ühilduvas base64 kodeeringus (Pythoni tugi) faili sisu.
URI näide: http://5.6.7.8:1215/file?id=7652354352
Keha näide 1:
{"status":200, "mime-type":"text/html", "content":
"PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTC..."}
Keha näide 2 (viga):
{"status":404}
Käsitlemise reeglid:
- Päringu algatav võrgusõlm saadab sõnumi naabrile, kellelt sama
id-gadownloadsõnumi vastu võttis - Kui eelmine samm ebaõnnestus, saadetakse sõnum kõigile naabritele
- Esimest korda selle sõnumi vastu võtmisel otsustab võrgusõlm, kas fail oli tema enda soovitud (
idparameeter)- Kui ei olnud, saadab võrgusõlm sõnumi edasi naabrile, kellelt saabus sama
id-gadownloadpäring - Kui eelmine samm ebaõnnestus (või sellist naabrit ei teata), saadetakse sõnum edasi kõigile naabritele, v.a. juhul kui naabri IP langeb kokku käsitletava
filesõnumi saatja IP-ga - Kui fail oli sõlme enda soovitud, parseeritakse päringu kehast staatus ja olemasolul faili sisu.
- Kui ei olnud, saadab võrgusõlm sõnumi edasi naabrile, kellelt saabus sama
- Teist korda sama (või enda algatatud)
id-ga sõnumi vastu võtmise korral seda ignoreeritakse
Soovitused
Praktikumi kirjeldus täieneb jooksvalt semestri käigus