HTTP

**HTTP** ( eli *[[hyperteksti]]n siirtoprotokolla*) on vuonna 1991 julkaistu tilaton protokolla, jonka avulla World Wide Web-järjestelmässä voidaan jakaa resursseja, kuten verkkosivuja ja tiedostoja. HTTP perustuu teknisesti TCP/IP -kuljetusprotokollaan ja toiminnallisesti asiakas-palvelin-arkkitehtuuriin, jossa asiakasohjelma, kuten verkkoselain, tekee palvelimelle pyynnön, johon palvelin vastaa.

HTTP:n on standardisoinut Internet Engineering Task Force (IETF) ja World Wide Web Consortium (W3C), joskin kehitys on myöhemmin siirtynyt IETF:n HTTP-työryhmälle "httpbis". Protokollan uusin versio on HTTP/3 (), joka julkaistiin kesäkuussa 2022.

HTTP:ta käytetään yleisesti sille varatulla porttilla 80 salaamattommaan liikenteeseen ja porttilla 443 salattuun liikenteeseen. HTTP on sovellustason eli OSI-mallin seitsemännen kerroksen protokolla. Se on tilaton, eli jokainen pyyntö käsitellään erillään aikaisemmista pyynnöistä.

## Historia

### Kehitys ja ensimmäiset versiot syntyvät
Vuonna 1989 CERN:illä työskennellyt Tim Berners-Lee teki esityksen internetin laajuisen hypertekstijärjestelmän rakentamista. Projektin nimi oli aluksi "Mesh", mutta myöhemmin se nimettiin uudelleen World Wide Webiksi sen toteutuksen aikana vuonna 1990. Järjestelmä koostui neljästä osasta, jotka rakennettiin jo olemassaolevan TCP/IP -protokollan päälle, joista yksi oli "yksinkertainen protokolla, jolla voi jakaa näitä hypertekstidokumentteja" eli HTTP. WWW:n muut kolme osaa olivat HTML, WorldWideWeb (selain) ja httpd ("http daemon", WWW-palvelin).

Ensimmäinen HTTP:n dokumentoitu versio julkaistiin vuonna 1991. Sillä ei ollut alun perin versionumeroa, mutta sitä alettiin kutsua myöhemmin versioksi 0.9, jotta se voitaisiin erottaa myöhemmistä versioista. Versio tuki vain GET-metodia, ja kaikki pyynnöt olivat yhden rivin pituisia. Palvelimen vastaukset olivat myös yksinkertaisia: ne sisälsivät pelkästään halutun HTML-tiedoston sisällön, eikä esimerkiksi kuvia ollut mahdollista välittää.

Vuosina 1991-1995 ominaisuuksia lisättiin palvelin- ja selainkehittäjien toimesta "yritys ja erehdys"-taktiikalla, jolloin katsottiin saako uusi ominaisuus kannatusta. Yhteensopivuusongelmat olivat myös yleisiä. Toukokuussa 1996 kirjoitettiin uusi dokumentti , joka määritteli HTTP:n version 1.0. Versiossa lisättiin tuki vastauksen onnistumis- ja virhekoodeille, otsaketiedoille (headers), PUT, DELETE, LINK ja UNLINK -metodeille ja muuntyyppisille tiedostoille kuin HTML otsakkeen Content-Type (sisällön tyyppi) johdosta. Ensimmäiselle riville lisättiin myös versionumero.

### Salattu HTTP eli HTTPS kehitetään

Vuoden 1994 lopulla Netscape-selain rakensi HTTP:n päälle salatun kuljetuskerroksen eli SSL:n (Secure Sockets Layer). Salattu yhteys mahdollisti ensimmäiset verkkokaupat. Vuonna 1999 SSL standardisoitiin (), ja se tunnetaan nykyään nimellä TLS (Transport Security Layer).

### Ensimmäinen standardisoitu versio julkaistaan
Versio HTTP/1.1 julkaistiin alkuvuodesta 1997, vain muutama kuukausi version 1.0 julkaisun jälkeen. Versio julkaistiin dokumentissa  ja sen kehitys tapahtui yhtä aikaa HTTP 1.0:n kanssa. Versio lisäsi useita parannuksia edeltäjäänsä:

* TCP-yhteyttä voitiin käyttää uudelleen, joka säästää aikaa. Yhteyttä ei tarvitse enää avata useita kertoja, jotta voidaan näyttää samassa dokumentissa olevat upotetut tiedostot.
* Protokollaa virtaviivaistettiin, mikä mahdollisti toisen pyynnön lähettämisen ennen kuin vastaus ensimmäiseen oli täysin lähetetty. Tämä laski kanssakäynnin latenssia.
* Isot tiedostot voitiin jakaa osiin (chunk)
* Lisättiin uusia välimuistitusta ohjaavia toimintoja
* Sisällön muodon (esim. kieli, enkoodaus, pakkaus ja tiedostomuoto) pyytäminen lisättiin.
* Host-otsakkeen avulla yksi IP-osoite pystyy tarjoamaan useita eri verkkosivustoja käyttäjille verkkotunnuksen perusteella.
* Uusia metodeja eli pyyntötyyppejä: OPTIONS, HEAD, POST, TRACE
** Versiosta 1.0 tuotiin myös metodit PUT ja DELETE
* Tuki pyynnön protokollan vaihdolle (Upgrade-otsake), jota hyödyntää esimerkiksi WebSocket-protokollan

Versiota HTTP/1.1 on päivitetty kaksi kertaa, ensin kesäkuussa 1999 dokumentissa  (kieliasua selkeytettiin ja mm. otsakkeiden ja virhekoodien käyttöä tarkennettiin) ja kesäkuussa 2014 dokumenteissa  (HTTP:n viestiformaatti) ja  (HTTP Basic-tunnistautuminen). 

### HTTP/2
Yli viidentoista vuoden aikana verkkosivuista tuli monimutkaisempia ja tiedostokooltaan suurempia. Internet Engineering Task Forcen (IETF) HTTP-työryhmä julkaisi HTTP/2:n (työnimellä HTTP 2.0) toukokuussa 2015 ().

HTTP/2-protokolla käyttää tiedonsiirrossa tekstin sijaan binääriä ja se on multipleksattu, jolloin pyyntöjä voidaan tehdä yhtä aikaa saman yhteyden yli. Se myös pakkaa otsakkeet, sillä ne sisältävät usein samaa tietoa.

Versiossa ei tullut muutoksia protokollan käyttöön, vaan muutokset olivat pääasiassa nopeusparannuksia. Uusi versio otettiin käyttöön nopeasti ympäri maailmaa, sillä se ei vaatinut muutoksia verkkosivustoihin ja -sovelluksiin ja käyttäjiltä vaadittiin vain ajan tasalla ollut selain. The Webmaster -julkaisun mukaan HTTP/2 on noin 14% nopeampi kuin edeltäjänsä.

Suurin osa suosituista selaimista tukee versiota HTTP/2 vain salatun HTTPS-yhteyden yli.

Aikaisemmin Google suunnitteli SPDY-protokollaa HTTP:n korvaajaksi, joka kuitenkin päätettiin hylätä HTTP/2:n tarjottua vastaavat edut. Samalla TLS-protokollan laajennukseksi suunniteltu NPN hylättiin, koska samat hyödyt tarjosi IETF:n ALPN-laajennus.

### HTTP/3

HTTP:n uusin versio HTTP/3 käyttää TCP:n sijaan UDP-protokollaan pohjautuvaa QUIC-protokollaa. HTTP/2:n tapaan muutokset ovat pääasiassa nopeusparannuksia, eikä protokollaan käyttöön tullut muutoksia.

HTTP/3 toimii nopeammin tilanteissa, joissa käyttäjä vaihtaa verkosta toiseen, esimerkiksi vaihtaessaan WiFi-verkosta mobiilidataan kotoa tai toimistolta lähdettäessä. QUIC-protokolla myös parantaa suorituskykyä tilanteissa joissa paketti ei saavuta päämääräänsä (packet loss), sillä tälläisesa tilanteessa HTTP/2:ssa kaikki muut paketit olisivat myös estyneet. HTTP/3:ssa tiedot lähetetään usean tietovirran (data stream) avulla, jonka ansiosta tieto voi jatkaa kulkemista muissa tietovirroissa kun yksi niistä on hetkellisesti tukkeutuneena. Muita hyötyjä ovat:

* Yhteyden muodostaminen on nopeampaa, sillä QUIC sallii TLS-salausavainten vaihdon samaan aikaan muiden kättelyiden (handshake) kanssa.
* Kättelyvaihe (handshake) voidaan ohittaa kokonaan, mikäli asiakasohjelma on yhdistänyt samalle palvelimelle aikaisemmin ja yhteyden tiedot ovat välimuistissa.
* Kaikki yhteydet ovat aina TLS-salattuja, eikä tarvetta erilliselle suojatulle protokollalle tai sen vaatimille ylimääräisille kättelyille ole enää. Salaus kattaa myös pyyntöjen metatiedon.

IETF muodosti QUIC-työryhmän vuonna 2016, joka kehitti projektia aluksi nimillä "HTTP-over-QUIC" ja "HTTP/2 Semantics Using The QUIC Transport Protocol". Lokakuussa 2018 projektin nimeksi vaihdettiin HTTP/3 projektin, jotta se ymmärrettäisiin erottaa QUIC-protokollasta. IETF julkaisi kesäkuussa 2022 HTTP/3:n standardiehdotuksen ().

Tammikuussa 2024 HTTP/3:a tuki 28% kaikista verkkosivustoista,  sekä suurin osa suosituimmista selaimista paitsi Safari.

## Laajennettavuus
HTTP:ta on muunneltu omiin tarpeisiin jo sen alkuajoilta lähtien. Sen päälle rakennettuja protokollia ovat muun muassa HTTPS, WebSocket ja SSE ().

HTTP:n otsakkeet mahdollistavat myös laajan muokattavuuden, ja osa kehittäjäyhteisön luomista otsikoista on myöhemmin standardisoitunut. Näitä ovat esimerkiksi DNT ( eli "älä seuraa") ja X-Frame-Options (upotettujen verkkosivujen hallintaan).

## Sivun hakeminen
Selain lähettää palvelimelle **GET-pyynnön**, johon palvelin vastaa.

Minimaalinen GET-pyyntö:

```
GET / HTTP/1.1
Host: www.example.com
```

Esimerkki pyytää `Host`-kentässä kerrotulta palvelimelta juuressa (`/`) olevan sisällön. Pyynnön URL on tällöin muotoa: ``.

### Pyyntö
Esimerkki pyynnöstä (tältä sivulta):

```
GET /wiki/HTTP HTTP/1.1
 Host: fi.wikipedia.org
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fi-FI; rv:1.6) Gecko/20040206 Firefox/0.8
 Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
 Accept-Language: fi,en;q=0.7,en-us;q=0.3
 Accept-Encoding: gzip,deflate
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
 Keep-Alive: 300
 Proxy-Connection: keep-alive
 Referer: http://fi.wikipedia.org/w/wiki.phtml?title=HTTP
 Cache-Control: max-age=0
```


Kentällä *Referer* selain kertoo sivulle, minkä sivun kautta kyseiselle sivulle on päädytty. Esimerkiksi palvelimelle kerrotaan, millä hakukoneen haulla sivulle on päädytty ellei sitä erikseen ole selaimen asetuksissa kielletty. Selain kertoo myös palvelimelle nimensä ja versionsa. Muut tiedot ovat lähinnä teknisiä ja kertovat minkä muotoisia tiedostoja selain osaa käsitellä ja millä kielellä käyttäjä mieluiten haluaisi sivua lukea.

Vanhempi HTTP 1.0 -protokolla vaati vain itse pyynnön, mutta HTTP 1.1 -protokollassa on määritettävä myös *Host*-otsake, joka kertoo palvelimen, johon selain *uskoo* ottavansa yhteyttä. Täten oikeasti saman IP-osoitteen takaa voikin löytyä useita www-sivuja, jotka palvelin lähettää aina kulloisenkin annetun host-otsakkeen perusteella. Tällaisia palvelimia kutsutaan *WWW-näennäispalvelimiksi*.

### Vastaus

```
HTTP/1.1 200 OK
 Date: Tue, 06 Jul 2004 17:59:22 GMT
 Expires: Thu, 01 Jan 1970 00:00:00 GMT
 Cache-Control: private, must-revalidate
 Via: 1.0 cthulhu
 Server: Apache/1.3.29 (Unix) PHP/4.3.4
 X-Powered-By: PHP/4.3.4
 Set-Cookie: fiwikiSession=a8015bd32eee4e5bd46fd83aea40f159; path=/
 Vary: Accept-Encoding,Cookie
 Content-Language: fi
 Content-Type: text/html; charset=utf-8
 X-Cache: MISS from wikipedia.org
 Transfer-Encoding: chunked
 Connection: keep-alive

 <!DOCTYPE html>
 ...
```


Vastauksessa pyyntöön välitetään ensimmäisenä HTTP-versio ja vastauksen tilakoodi (tässä tapauksessa 200 OK), joka kertoo pyynnön onnistumisesta tai virheestä. Tämän jälkeen seuraa otsaketiedot (headers), jotka on eroteltu rivinvaihdolla. Kentän nimi ja arvo erotellaan tuplapisteellä*.*

Otsakkeista välittyy esimerkiksi dokumentin tyyppi (MIME-tyyppinä, esimerkissä HTML, UTF-8-merkistökoodauksella) ja sisällön kieli (suomi). Vastauksen *Expires*-otsakkeen arvo (voimassaoloaika) on Unix-järjestelmän ajan alkuhetki vuonna 1970, mikä tarkoittaa, että sivu vanhenee välittömästi, eikä sitä pidä tallentaa välipalvelimeen uudelleen käytettäväksi. Tähän voi olla useita syitä. Esimerkiksi pyyntö oli sivun muokkausta varten, eikä vanhentuneen sisällön käsittely enää tulevaisuudessa ole järkevää tai käyttäjä voi olla kirjautunut tunnuksellaan, jolloin sivua ei voi näyttää muille käyttäjille. Otsake *Cache-Control* kertoo saman asian, mutta tarkemmin.

Otsakkeen *Set-Cookie* avulla voidaan pyytää selainta tallentamaan eväste (*cookie*), jonka se palauttaa palvelimelle seuraavan pyynnön yhteydessä omassa *Cookie*-otsakkeessa.

Otsaketietodot päättyvät kahteen rivinvaihtoon (tai tyhjään riviin). Tämän jälkeen palvelin lähettää varsinaisen näytettävän sisällön.

## Metodit
GET on **metodi**, jolla luetaan yksittäinen sivu tai resurssi. HTTP määrittelee kuitenkin muitakin metodeja (vaikka valtaosa liikenteestä käyttää vain GET-metodia); erityisesti GET on määritelty idempotentiksi, jolloin peräkkäisten, identtisten GET-pyyntöjen pitäisi tuottaa aina sama tulos. Toinen käytetty metodi on POST, jolla välitetään palvelimelle muun muassa selaimessa muokattavien tekstikenttien (lomakkeiden) sisällöt. POST ei ole idempotentti, joten useimpien järjestelmän tilaa muuttavien kutsujen tulisi käyttää sitä GETin sijaan. HEAD-metodilla voidaan pyytää pelkät otsikkokentät ilman sivun sisältöä. Tätä käytetään esimerkiksi tarkistettaessa onko dokumentti muuttunut sitten viime kerran siirtämättä sitä kokonaan. CONNECT-metodia käytetään taas salattujen (HTTPS) yhteyksien kanssa. Muita metodeita on harvoin edes toteutettu WWW-palvelimeen, ellei samalla tueta myös WebDAV-laajennuksia.

* GET - käytetään resurssin hakua varten (esimerkiksi verkkosivun hakuun)
* POST - esimerkiksi täytetyn lomakkeen tietojen lähettäminen palveluun
* OPTIONS - kysely palvelimen tai resurssin ominaisuuksista
* HEAD - pyydä vain sivun otsikkotiedot (esimerkiksi hakukone selvittää onko sivu muuttunut)
* PUT - sivun tallettaminen (käytetään harvoin ilman WebDAV-laajennuksia)
* DELETE - sivun poistaminen (käytetään harvoin ilman WebDAV-laajennuksia)
* TRACE - palauttaa pyynnön sellaisenaan (vikojen jäljitykseen)
* CONNECT - pyydetään yhteyttä, joka jää päälle

## Vastauskoodit

Palvelin palauttaa onnistuneeseen sivunhakuun (edellä) vastauksena ensimmäisenä "HTTP/1.1 200 OK". Tämä kertoo protokollan versionumeron ja koodi "200" kertoo pyynnön onnistuneen (selväkielisenä "OK"). Statuskoodeista 2xx-alkuiset kertovat onnistuneesta pyynnöstä. Näistä tärkeimpiä ovat 200 eli OK ja 206 "Partial Content", joka kertoo vastauksen olevan osa pyydetty osa tiedostoa (pyydettäessä osaa suuremmasta tiedostosta).

3xx-alkuiset koodit kertovat sisällön löytyvän jostain muualta kuin selain pyysi. Koodi 301 "Moved Permanently" kertoo sivun siirtyneen pysyvästi ja 302 "Moved Temporarily" väliaikaisesti toiseen paikkaan.

4xx-alkuiset vastauskoodit kertovat asiakasohjelman (selaimen) tekemästä virheestä. Esimerkiksi 404 "Not Found" on tuloksena, jos haetaan sivua, jota palvelimella ei ole ja 403 "Forbidden", ettei hakijalla ole oikeutta dokumenttiin pääsyyn.

5xx-alkuiset koodit ovat palvelimen tekemien virheiden seurausta. Näistä yleisin on 500 "Internal Server Error", joka kertoo pyynnön epäonnistuneen sitä käsittelevän ohjelman kaaduttua tai palvelimen muun virheellisen toiminnan seurauksena.

Vastauskoodeja käytetään verrattain vähän, vaikka niiden avulla voitaisiin toteuttaa monia hyviä ominaisuuksia, esimerkiksi www-selain voisi
sopivan vastauskoodin saadessaan tietää, että URL ei ole enää olemassa, mutta että se löytyy annetusta osoitteesta ja päivittää automaattisesti kirjanmerkin uutta vastaavaksi.

## Istunnot
HTTP on normaalisti *tilaton*. Tämä tarkoittaa, ettei seuraavan pyynnön tulos riipu mitenkään edellisen tuloksesta ja kaikki asiakkaat saavat saman tuloksen samalla pyynnöllä. Tämä on kuitenkin melko rajoitettua, koska esimerkiksi verkkokaupan ostoskori tai kirjautuminen käyttäjätunnuksella foorumille olisivat mahdottomia tilattomalla protokollalla.

Käyttäjien *[[istunto]]jen* (*session*) toteuttamiseen HTTP:ssä on useita keinoja. Luotettavimmat näistä liittyvät evästeiden (*cookie*) käyttöön. Tällöin palvelin asettaa asiakasohjelmalle evästeen *Set-Cookie*-kentällä pyynnön yhteydessä. Vastaavasti palvelimelle luodaan ja pidetään muistissa istuntoon liittyvä tieto. Istunnon voisi muodostaa luottamalla pelkästään evästeiden välittämään tietoon, mutta tämä on usein hankalaa ja mahdollisesti tietoturvariski. Tietoturvan ylläpitämiseksi istunto sidotaan myös käyttäjän IP-osoitteeseen, johon luottaminen ainoana istunnon tunnisteena on epävarmaa (mm. siksi, että usea eri käyttäjä voi hakea sivuja saman IP-osoitteen takaa. Katso osoitteenmuunnos) Myös evästeisiin luottaminen on suhteellisen epävarmaa, koska niille varattu tila on rajattu ja monet käyttäjät estävät ainakin epämääräisten evästeiden käytön. Istuntoon liittyvä tilatieto voidaan välittää myös URL:n yhteydessä parametrina, mutta sekin on ongelmallista väärin toteutettuna. Vastaavasti palvelimen kapasiteetti on rajallinen, joten vanhoja ja käyttämättömiä istuntoja on siivottava pois tietyin väliajoin, mikä saa liian kauan käyttämättömä olevan istunnon katkeamaan.

## Standardointi
*  - *Hypertext Transfer Protocol -- HTTP/1.0*
*  - *HTTP 1.1* (vanhempi versio)
*  - *HTTP 1.1* (vanhentunut)
* 
* 
* 
* 
* 
* 
*  - *Hypertext Transfer Protocol Version 2 (HTTP/2)*
*  - *HTTP/3*

HTTP-protokollalle on varattu TCP-portti 80. Toinen varattu, mutta harvoin käytetty, portti on 8080. Toisaalta portti 8080 on monien verkkosovelluspalvelimien, kuten Tomcatin, JBossin ja Glassfishin oletusportti. Portin 8080 käyttö on niin ikään yleistä testiympäristöissä.

## Katso myös
* WebDAV
* DeltaV
* Apache

## Lähteet

## Aiheesta muualla