Osa 1

Internetin perusosat

Internetin perustana ovat (1) palveluiden, palvelinohjelmistojen ja resurssien yksilöintiin käytetyt merkkijonomuotoiset osoitteet (URI, Uniform Resource Identifier) sekä näiden merkkijonomuotoisten osoitteiden verkko-osoitteiksi muuntamiseen käytettävä palvelu (DNS, Domain Name Services), (2) selainten ja palvelinten välisessä viestittelyssä käytettävä viestimuoto eli protokolla (HTTP, HyperText Transfer Protocol), sekä (3) yhteinen dokumenttien esityskieli (HTML, HyperText Markup Language).

Näiden kolmen peruspilarin — URI, HTTP ja HTML — lisäksi internetin mahdollistaa verkkoliikenne sekä siihen liittyvät protokollat kuten TCP ja TCP/IP. Jälkimmäisiin syvennytään tarkemmin kurssilla Tietoliikenteen perusteet (TKT-20004).

Yksinkertaisenkin verkkosivun hakemiseen liittyy monta askelta. Kun kirjoitat osoitteen selaimen osoitepalkkiin ja painat enteriä, seuraavat tapahtumat tapahtuvat.

  1. Käyttäjä kirjoittaa osoitteen (URI, URL) selaimen osoitepalkkiin ja painaa hae.
  2. Jos osoite on tekstimuotoinen osoite, esim. mooc.fi, selain ottaa yhteyden DNS-palvelimeen ja hakee DNS-palvelimelta tekstimuotoista osoitetta vastaavan IP-osoitteen.
  3. Selain ottaa yhteyden IP-osoitteessa toimivaan palvelimeen ja lähettää sinne HTTP-pyynnön.
  4. Palvelin vastaanottaa pyynnön ja käsittelee sen. Jos käyttäjän pyytämä sivu — esimerkiksi HTML-sivu — löytyy palvelimelta, palvelin palauttaa sivun käyttäjälle. Jos sivua ei löydy, palvelin palauttaa virheviestin.
  5. Selain vastaanottaa palvelimen palauttaman vastauksen ja yhteys palvelimelle suljetaan.
  6. Selain käsittelee palvelimen palauttaman vastauksen. Mikäli vastaus on HTML-sivu, selain käy sen läpi elementti elementiltä erikseen haettavia resursseja kuten kuvia, tyylitiedostoja, javascript-tiedostoja, ym, tunnistaen. Käyttäjälle voidaan näyttää tässä vaiheessa jo osa sivusta.
  7. Selain hakee jokaisen erikseen haettavan resurssin erillisessä resurssikohtaisessa HTTP-pyynnössä.
  8. Kun sivu on käsitelty ja kaikki siihen liittyvät resurssit on haettu ja käsitelty, sivu näkyy käyttäjälle kokonaan ladattuna

Tarkastellaan edellisessä tapahtumaketjussa esiintyneitä termejä hieman tarkemmin.

URI ja DNS: Osoitteet ja niiden tulkinta

Verkossa sijaitseva resurssi tunnistetaan osoitteen perusteella. Osoite (URI eli Uniform Resource Identifier, myös terminä käyttöön jäänyt URL Uniform Resource Locator) koostuu resurssin nimestä ja sijainnista, joiden perusteella haluttu resurssi ja palvelin (sijainti) voidaan löytää verkossa olevien koneiden massasta.

Termi resurssi tulee ajalta, jolloin verkkosivut olivat lähinnä staattisia dokumentteja, mutta se vastaa oikeastaan mitä tahansa verkosta haettavaa sisältöä. URI-osoitteet näyttävät seuraavilta:

protokolla://isäntäkone:portti/
  • protokolla: kyselyssä käytettävä protokolla, esimerkiksi HTTP tai HTTPS.
  • isäntäkone: kone tai palvelin johon luodaan yhteys. Voi olla joko IP-osoite tai tekstuaalinen kuvaus (esim mooc.fi tai www.hs.fi).
  • portti: mikäli portin jättää osoitteesta pois, tehdään pyyntö tyypillisesti protokollan oletusporttiin — esimerkiksi HTTP-protokollan portti on oletuksea 80. Salatun HTTP-protokollan (HTTPS) portti on onoletuksena 443.

Osoitteissa voi olla lisäksi polku, tietoa haettavasta dokumentista, kyselyparametreja sekä ankkuri. Nämä kaikki, kuten myös portti, ovat valinnaisia.

polku/kohdedokumentti.paate?kyselyparametri=arvo&toinen=arvo#ankkuri
  • polku: polku resurssiin palvelimella, esim https://www.hs.fi/uutiset.
  • kohdedokumentti ja .paate: haettava resurssi sekä sen tiedostotyyppi, esim lista.pdf.
  • kyselyparametrit: koostuu avain-arvo -pareista, joiden avulla palvelimelle pystyy toteuttamaan lisätoiminnallisuutta. Kuhunkin avaimeen liittyvä arvo annetaan =-merkillä eroteltuina, avain-arvo -parit erotetaan toisistaan &-merkillä.
  • ankkuri: kertoo mihin kohtaan dokumentissa tulee mennä.

Yhdessä edellisten avulla tunnistetaan protokolla ja kone sekä koneesta haettava resurssi.

Kun käyttäjä kirjoittaa web-selaimen osoitekenttään osoitteen ja painaa enteriä, web-selain tekee kyselyn annettuun osoitteeseen. Koska tekstimuotoiset osoitteet ovat käytännössä vain ihmisiä varten, kääntää selain ensiksi halutun tekstimuotoisen osoitteen IP-osoitteeksi. Jos IP-osoite on jo tietokoneen tiedossa esimerkiksi aiemmin osoitteeseen tehdyn kyselyjen takia, selain voi ottaa yhteyden IP-osoitteeseen. Jos IP-osoite taas ei ole tiedossa, tekee selain ensin kyselyn DNS-palvelimelle (Domain Name System), jonka tehtävänä on muuntaa tekstuaaliset osoitteet IP-osoitteiksi (esim. Helsingin yliopiston kotisivu https://www.helsinki.fi on IP-osoitteessa 128.214.189.90).

IP-osoitteet yksilöivät tietokoneet ja mahdollistavat koneiden löytämisen verkon yli. Käytännössä yhteys IP-osoitteen määrittelemään koneeseen avataan sovelluskerroksen HTTP-protokollan avulla kuljetuskerroksen TCP-protokollan yli. TCP-protokollan tehtävänä on varmistaa, että viestit pääsevät perille. Selain ei ota "suoraan" yhteyttä palvelinohjelmistoon, vaan välissä on tyypillisesti useita viestinvälityspalvelimia, jotka auttavat viestin perillepääsemisessä.

HTTP: Selainten ja palvelinten välinen kommunikaatioprotokolla

HTTP (HyperText Transfer Protocol) on sovellustason protokolla, jota web-palvelimet ja selaimet käyttävät kommunikointiin. HTTP-protokolla perustuu asiakas-palvelin malliin, jossa jokaista pyyntöä kohden on yksi vastaus (request-response paradigm). Tämä tarkoittaa sitä, että jokainen pyyntö käsitellään erillisenä kokonaisuutena, eikä saman käyttäjän kahta peräkkäistä pyyntöä yhdistetä automaattisesti toisiinsa.

Käytännössä HTTP-asiakasohjelma (jatkossa selain) lähettää viestin palvelimelle, joka palauttaa HTTP-protokollan mukaisen vastauksen. Tällä hetkellä eniten käytetty HTTP-protokollan versio on 1.1, joka on määritelty RFC 2616-spesifikaatiossa.

Tutustutaan seuraavaksi tarkemmin HTTP-protokollaan, eli selainten ja palvelinten väliseen kommunikaatioon käytettyyn kommunikaatiotyyliin.

HTTP-viestin rakenne: palvelimelle lähetettävä kysely

HTTP-protokollan viestit ovat tekstimuotoisia. Viestit koostuvat riveistä jotka muodostavat otsakkeen, sekä riveistä jotka muodostavat viestin rungon. Viestin runkoa ei ole pakko olla olemassa — joskus palautetaan esimerkiksi vain uudelleenohjaukseen ohjeistava viesti. Viestin loppuminen ilmoitetaan kahdella peräkkäisellä rivinvaihdolla.

Palvelimelle lähetettävän viestin, eli kyselyn, ensimmäisellä rivillä on pyyntötapa, halutun resurssin polku ja HTTP-protokollan versionumero.

PYYNTÖTAPA /POLKU_HALUTTUUN_RESURSSIIN HTTP/versio
otsake-1: arvo
otsake-2: arvo

valinnainen viestin runko

Pyyntötapa ilmaisee HTTP-protokollassa käytettävän pyynnön tavan (esim. GET tai POST). Polku haluttuun resurssiin kertoo haettavan resurssin sijainnin palvelimella ja se voi sisältää URI:n osat polku, kohdedokumentti ja pääte, kyselyparametrit, sekä ankkurin (esim. /uutiset/index.html?rajaa=10#uusin). HTTP-versio kertoo käytettävän version (esim. HTTP/1.0).

Alla esimerkki hyvin yksinkertaisesta — joskin yleisestä — pyynnöstä. Huomaa että yhteys palvelimeen on HTTP-protokollalla tapahtuvan viestittelyn kohdalla jo muodostettu — HTTP-protokolla ei siis liity yhteyden muodostamiseen.

GET /index.html HTTP/1.0

Yleisesti käytössä oleva HTTP/1.1 -protokolla mahdollistaa useamman palvelimen pitämisen samassa IP-osoitteessa virtuaalipalvelintekniikan avulla. Tällöin yksittäiset palvelinkoneet voivat sisältää useita palvelimia. Käytännössä IP-osoitetta kuunteleva kone voi joko itsessään sisältää useita ohjelmistoilla emuloituja palvelimia, tai se voi toimia reitittimenä ja ohjata pyynnön tietylle esimerkiksi yrityksen sisäverkossa sijaitsevalle koneelle.

Koska yksittäinen IP-osoite voi sisältää useampia palvelimia, pelkkä polku haluttuun resurssiin ei riitä oikean resurssin löytämiseen: resurssi voisi olla millä tahansa koneeseen liittyvällä virtuaalipalvelimella. HTTP/1.1 -protokollassa on pyynnöissä pakko olla mukana käytetyn palvelimen osoitteen kertova Host-otsake.

GET /index.html HTTP/1.1
Host: www.munpalvelin.net

Käytännössä tämä tarkoittaa sitä, että samassa IP-osoitteessa voi olla useita "alipalvelimia". Kun haet osoitetta tekstimuotoisella osoitteella, selain lähettää viestin yhteydessä Host-otsakkeen, jonka perusteella IP-osoitteeseen vastaava palvelin päättelee alipalvelimen.

HTTP-viestin rakenne: palvelimelta saapuva vastaus

Palvelimelle tehtyyn pyyntöön saadaan aina jonkinlainen vastaus. Jos tekstimuotoiseen osoitteeseen ei ole liitetty IP-osoitetta DNS-palvelimilla, selain ilmoittaa ettei palvelinta löydy. Jos palvelin löytyy, ja pyyntö saadaan tehtyä palvelimelle asti, tulee palvelimen myös vastata jollain tavalla.

Palvelimelta saatavan vastauksen sisältö on seuraavanlainen. Ensimmäisellä rivillä on HTTP-protokollan versio, viestiin liittyvä statuskoodi, sekä statuskoodin selvennys. Tämän jälkeen on joukko otsakkeita, tyhjä rivi, ja mahdollinen vastausrunko. Vastausrunko ei ole pakollinen.

HTTP/versio statuskoodi selvennys
otsake-1: arvo
otsake-2: arvo

valinnainen vastauksen runko

Esimerkiksi:

HTTP/1.1 200 OK
Date: Mon, 01 Sep 2014 03:12:45 GMT
Server: Apache/2.2.14 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 973
Connection: close
Content-Type: text/html;charset=UTF-8

.. runko ..

Kun palvelin vastaanottaa tiettyyn resurssiin liittyvän pyynnön, tekee se resurssiin liittyviä toimintoja ja palauttaa lopulta vastauksen. Kun selain saa vastauksen, tarkistaa se vastaukseen liittyvän statuskoodin ja siihen liittyvät tiedot — tyypillinen statuskoodi on 200 (OK). Tämän jälkeen selain päättelee, mitä vastauksella tehdään, ja esimerkiksi näyttää vastaukseen liittyvän sisällön kuten web-sivun käyttäjälle.

HTTP-statuskoodit

Statuskoodit (status code) kuvaavat palvelimella tapahtunutta toimintaa kolmella numerolla. Statuskoodien avulla palvelin kertoo mahdollisista ongelmista tai tarvittavista lisätoimenpiteistä. Yleisin statuskoodi on 200, joka kertoo kaiken onnistuneen oikein. HTTP/1.1 sisältää viisi kategoriaa vastausviesteihin.

  • 1**: informaatioviestit (esim 100 "Continue")
  • 2**: onnistuneet tapahtumat (esim 200 "OK")
  • 3**: asiakasohjelmistolta tarvitaan lisätoimintoja (esim 301 "Moved Permanently" tai 304 "Not Modified" eli hae välimuistista)
  • 4**: virhe pyynnössä tai erikoistilanne (esim 401 "Not Authorized" ja 404 "Not Found")
  • 5**: virhe palvelimella (esim 500 "Internal Server Error")
Lista lähes kaikista HTTP-statuskoodeista löytyy osoitteesta https://en.wikipedia.org/wiki/ListofHTTPstatuscodes.

HTTP-liikenteen testaaminen telnet-työvälineellä

Linux-ympäristöissä on käytössä telnet-työkalu, jota voi käyttää yksinkertaisena asiakasohjelmistona pyyntöjen simulointiin. Telnet-yhteyden tietyn koneen tiettyyn porttiin saa luotua komennolla telnet isäntäkone portti. Esimerkiksi Helsingin sanomien www-palvelimelle saa yhteyden seuraavasti:

Esimerkkitulostus

$ telnet www.hs.fi 80

Tätä seuraa telnetin infoa yhteyden muodostamisesta, jonka jälkeen pääsee kirjoittamaan pyynnön.

Esimerkkitulostus

Trying 13.32.56.28... Connected to www.hs.fi. Escape character is '^]'.

Yritetään pyytää HTTP/1.1 -protokollalla juuridokumenttia. Huom! HTTP/1.1 -protokollassa tulee pyyntöön lisätä aina Host-otsake. Jos yhteys katkaistaan ennen kuin olet saanut kirjoitettua viestisi loppuun, ota apuusi tekstieditori ja copy-paste. Muistathan myös että viesti lopetetaan aina kahdella rivinvaihdolla.

Esimerkkitulostus

GET / HTTP/1.1 Host: www.hs.fi

Palvelin palauttaa vastauksen, jossa on statuskoodi ja otsakkeita sekä dokumentin runko.

Esimerkkitulostus

HTTP/1.1 301 Moved Permanently Server: CloudFront Date: Sun, 03 Mar 2019 09:20:36 GMT Content-Type: text/html Content-Length: 183 Connection: keep-alive Location: https://www.hs.fi/ X-Cache: Redirect from cloudfront Via: 1.1 a529b95d300020af7b6819ecefd572f4.cloudfront.net (CloudFront) X-Amz-Cf-Id: a8UnDgQydT2LUbo-uKy49aeZP-QgDFnMvJ43CRMxvFbuTd1zxDDRIA==

<html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>CloudFront</center> </body> </html>

Yllä olevassa esimerkissä palvelimelta www.hs.fi sisältöä haettaessa palvelin vastaa "HTTP/1.1 301 Moved Permanently". Viestillä palvelin kertoo, että sisältöjä tulee hakea salatun HTTPS-protokollan yli. HTTPS-protokollaa noudattavien sivujen tarkastelu on hieman haastavampaa telnet-yhteyden yli, sillä viestittelyn tulee olla salattua — tähän telnet ei tarjoa tukea.

Eräs vaihtoehto on Linux-koneilla HTTPS-yhteyden yli tapahtuvien viestien tarkasteluun on GnuTLS kirjasto. Tämän avulla suojatun HTTP-yhteyden muodostaminen ja tarkastelu onnistuu suoraviivaisesti.

Esimerkkitulostus

$ gnutls-cli www.hs.fi

Processed 148 CA certificate(s). Resolving 'www.hs.fi'... Connecting to '13.32.56.44:443'... Certificate type: X.509 Got a certificate list of 4 certificates. ...

GET / HTTP/1.1 Host: www.hs.fi

// .. palvelin tulostaa vastauksen tänne

Jos käytössäsi ei ole Linux-konetta, voit käyttää Telnetiä esimerkiksi PuTTY-ohjelmiston avulla. Voit myös tehdä selailua käsin hieman myöhemmin toteutettavan Java-ohjelman avulla.

HTTP-protokollan pyyntötavat

HTTP-protokolla määrittelee kahdeksan erillistä pyyntötapaa (Request method), joista eniten käytettyjä ovat GET ja POST. Pyyntötavat määrittelevät rajoitteita ja suosituksia viestin rakenteeseen ja niiden prosessointiin palvelinpäässä.

Tiedon hakeminen: GET

GET-pyyntötapaa käytetään esimerkiksi dokumenttien hakemiseen: kun kirjoitat osoitteen selaimen osoitekenttään ja painat enter, selain tekee GET-pyynnön. GET-pyynnöt eivät tarvitse otsaketietoja HTTP/1.1:n vaatiman Host-otsakkeen lisäksi. Mahdolliset kyselyparametrit lähetetään palvelimelle osana haettavaa osoitetta.

GET /sivu.html?parametri=arvo HTTP/1.1
Host: palvelimen-osoite.net

Tiedon lähettäminen: POST

POST-pyyntötapaa käytetään tiedon lähettämiseen. Käytännön ero POST- ja GET-kyselyn välillä on se, että POST-tyyppisillä pyynnoillä kyselyparametrit liitetään pyynnön runkoon. Rungon sisältö ja koko määritellään otsakeosiossa. POST-kyselyt mahdollistavat multimedian (kuvat, videot, musiikki, ...) lähettämisen palvelimelle.

POST /sivu.html HTTP/1.1
Host: palvelimen-osoite.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

parametri=arvo

Muita pyyntötyyppejä

Selaimen ja palvelimen välisessä kommunikoinnissa GET- ja POST-tyyppiset pyynnöt ovat eniten käytettyjä. Sivun tai siihen liittyvän osan kuten kuvan hakeminen tapahtuu käytännössä aina GET-tyyppisellä pyynnöllä, ja tiedon lähettäminen esimerkiksi lomakkeen kautta POST-tyyppisellä pyynnöllä. HTTP-protokolla määrittelee muitakin pyyntötyyppejä, joita käytetään palvelinohjelmistojen toteuttamisessa. Oleellisimpia ovat:

  • OPTIONS pyytää tietoja resurssiin liittyvistä vaihtoehdoista (esimerkiksi voidaanko resurssi poistaa, ...)
  • DELETE pyytää resurssin poistamista
  • HEAD haluaa resurssiin liittyvät otsaketiedot, mutta ei resurssia

HTML: Yhteinen dokumenttien esityskieli

HTML on rakenteellinen kuvauskieli, jolla voidaan esittää linkkejä sisältävää tekstiä sekä tekstin rakennetta. HTML koostuu elementeistä, jotka voivat olla sisäkkäin ja peräkkäin. Elementtejä käytetään ohjeina dokumentin jäsentämiseen ja käyttäjälle näyttämiseen. HTML-dokumenteissa elementit avataan elementin nimen sisältävällä pienempi kuin -merkillä < alkavalla ja suurempi kuin -merkkiin > loppuvalla merkkijonolla (<elementin_nimi>), ja suljetaan merkkijonolla jossa elementin pienempi kuin -merkin jälkeen on vinoviiva (</elementin_nimi>).

HTML-dokumentin rakennetta voi ajatella myös puuna. Juurisolmuna on elementti <html>, jonka lapsina ovat elementit <head> ja <body>.

Jos elementin sisällä ei ole muita elementtejä tai tekstisolmuja eli tekstiä, voi elementin yleensä avata ja sulkea samalla merkkijonolla: (<elementin_nimi />).

HTML:stä on useita erilaisia standardeja, joista viimeisin julkaistu versio löytyy osoitteesta https://www.w3.org/TR/html/.

<!DOCTYPE html>
<html lang="fi">
  <head>
    <meta charset="UTF-8" />
    <title>selainikkunassa näkyvä otsikko</title>
  </head>
  <body>
    <p>
      Tekstiä tekstielementin sisällä, tekstielementti
      runkoelementin sisällä, runkoelementti html-elementin
      sisällä. Elementin sisältö voidaan asettaa useammalle
      riville.
    </p>
  </body>
</html>

Ylläoleva HTML-dokumentti sisältää dokumentin tyypin ilmaisevan aloitustägin (<!DOCTYPE html>), dokumentin aloittavan html-elementin (<html>), otsake-elementin ja sivun otsikon (<head>, jonka sisällä <title>), sekä runkoelementin (<body>).

Elementit voivat sisältää attribuutteja ja attribuuteille voi antaa arvoja. Esimerkiksi ylläolevassa esimerkissä html-elementille on määritelty erillinen attribuutti lang, joka kertoo dokumentissa käytetystä kielestä. Ylläolevan esimerkin otsakkeessa on myös metaelementti, jota käytetään lisävinkin antamiseen selaimelle: "dokumentissa käytetään UTF-8 merkistöä". Tämä kannattaa olla dokumenteissa aina.

Nykyaikaiset web-sivut sisältävät paljon muutakin kuin sarjan HTML-elementtejä. Linkitetyt resurssit, kuten kuvat ja tyylitiedostot, ovat oleellisia sivun ulkoasun ja rakenteen luomisessa. Selainpuolella suoritettavat skriptitiedostot, erityisesti Javascript, ovat luoneet huomattavan määrän syvyyttä nykyaikaiseen web-kokemukseen. Internet on kasvanut myös käsitteenä tällä sivulla tarkastellun perinteisen "1980"-luvun internetin jälkeen. Esimerkiksi esineiden internet (Internet of Things) eli kaikkien laitteiden kytkeminen verkkoon tulee muokkaamaan koko käsitystämme internetistä.

Pääsit aliluvun loppuun! Jatka tästä seuraavaan osaan:

Muistathan tarkistaa pistetilanteesi materiaalin oikeassa alareunassa olevasta pallosta!