2005-05-22

Otsakkeiden lyhyt oppimäärä

Jokainen meistä on varmasti kuullut peruspiirteet siitä, miten HTTP-yhteys toimii. Selain tekee palvelimelle kyselyn (request), jonka perusteella palvelin tuottaa vastauksen (response). Kysely on esimerkiksi "anna minulle polussa /tuotteet/index.html sijaitseva resurssi" ja vastaus useimmiten "tässäpä tämä". Eli teknisemmin, GET /tuotteet/index.html HTTP/1.1 ja HTTP/1.1 200 OK .

Vähemmän tunnettua on, että niin kyselyn kuin vastauksen mukana seuraa koko joukko otsakkeita (header). Kyselyn otsakkeet kertovat erityisesti selaimesta ja sen tukemista tiedostomuodoista. Vastauksen otsakkeet puolestaan kertovan minkä muotoinen tiedosto lopulta palautettiin ja miten sitä tulisi käsitellä.

Ennen jatkamista on hyvä hankkia sopivat työkalut. Helpoimmalla pääsee käyttämällä Webissä sijaitsevaa kyselyntekijää, esimerkiksi tätä Rex Swainin tarjoamaa. Mozilla-pohjaisten selainten käyttäjät voivat myös ladata erittäin hyödyllisen LiveHTTPHeaders-laajennoksen, joka näyttää otsakkeet miltä tahansa sivulta, myös jälkikäteen. Melkein pakollinen väline Web-sovellusten kehittäjille, sanoisin.

Tämä juttu keskittyy enemmän vastauksen otsakkeisiin. Esimerkiksi Tampereen yliopiston etusivun eli http://www.uta.fi/ mukana seuraa tällainen rimpsu:

HTTP/1.1 200 OK
Date: Sat, 21 May 2005 18:38:17 GMT
Server: Apache/1.3.33 (Unix)
Last-Modified: Fri, 20 May 2005 11:51:10 GMT
ETag: "479a0-1578-428dcf2e"
Accept-Ranges: bytes
Content-Length: 5496
Connection: close
Content-Type: text/html; charset=iso-8859-1


Ensimmäinen rivi ei oikeastaan ole otsake, vaan tilarivi (status line) ja se jätetään myös tässä tarkastelun ulkopuolelle. Seuraavat merkitykseltään selvät otsakkeet käydään myös läpi nopeasti:

Date (palvelimen kellon aika lähetyshetkellä)
Server (palvelinohjelmistoa kuvaava määrämuotoinen rivi)
Accept-Ranges (ilmoitus siitä, että palvelin osaa pyydettäessä toimittaa tietyn osan resurssista)
Content-Length (vastauksen sisältöosan pituus tavuina)
Connection (close kertoo, että palvelin aikoo sulkea yhteyden vastauksen jälkeen, keep-alive tarkoittaisi palvelimen olevan valmis vastaanottamaan toisen kyselyn samalla yhteyskerralla)

Ensimmäinen erityisen mielenkiintoinen otsake on Content-Type. Otsakkeessa kerrotaan, minkä tyyppinen vastauksen sisältöosa on. Tässä tapauksessa palvelin kertoo palautetun tiedoston olevan tyypiltään text/html eli HTML-tiedosto. Se olisi voinut myös olla vaikkapa image/png eli PNG-muotoinen kuva. Esimerkkivastauksessa palvelin tarkensi vielä tyyppiä ja kertoi tiedoston merkkikoodauksen olevan ISO Latin 1.

Selaimen tulisi tunnistaa vastauksen tiedostotyyppi kokonaan Content-Type -otsakkeen perusteella, eikä esimerkiksi yrittää arvailla tiedostopäätettä kyselystä. HTTP:n näkökulmasta index.html on ainoastaan osa resurssin sijaintia (index piste html) eikä kerro mitään sen tyypistä. Luonnollisesti Internet Explorer toimi kauan väärin tässä asiassa, kunnes jokin Service Pack muutti tilanteen ja aiheutti harmia asiasta tietämättömille ylläpitäjille. Olisi ehkä kannattanut korjata palvelimen säädöt siinä vaiheessa kun Mozilla-käyttäjät valittivat asiasta.

Toisia tärkeitä tapauksia ovat Last-Modified, ETag ja esimerkistä puuttuva Cache-Control. Näiden käytännön vaikutus on välimuistien ja välityspalvelinten toiminnan sääteleminen.

Last-Modified kertoo, milloin resurssia muutettiin edellisen kerran. Kun selain tietää tämän, se voi seuraavan kerran tehdä ehdollisen kyselyn (conditional request), esimerkiksi "anna minulle resurssi jos se on muuttunut edellisen kyselyn jälkeen". Jos resurssi ei ole muuttunut, tulee paluupostissa tieto asiasta ja selain pystyy käyttämään välimuistista löytyvää kappaletta resurssista.

ETag sisältää entity tagin eli vastauksen sisältämää resurssia kuvaavan tunnisteen. Kun resurssi muuttuu, tulee myös sen entity tagin muuttua samalla. Selain pystyy tekemään ehdollisen kyselyn myös entity tagin pohjalta. Syvästi kiinnostuneiden kannattanee vilkaista liittyvää kohtaa RFC:stä, muiden kannattaa puolestaan unohtaa, että mainitsin koko entity tagit.

Cache-Control sisältää erityisohjeita siitä, saako vastauksen mukana saapuneen resurssin tallentaa välimuistiin, ja jos saa, niin millä ehdoilla. Jos otsaketta ei palauteta, käytetään oletuksia. Otsakkeen arvoista esimerkiksi public kertoisi, että resurssin voi tallentaa oletuksia laajemmin, private estää tallentamiseen jaettuihin välimuisteihin. Tiukin määritys on no-store, joka kieltää kaiken tallentamisen.

Palvelin pystyisi kertomaan myös esimerkiksi palautetun resurssin kielen (Content-Language), vanhenemishetken (Expires) ja minkä kyselyn otsakkeiden muuttuminen muuttaa palautettua resurssia (Vary). Muut otsakkeet ja linkit liittyviin HTTP/1.1-määrityksen kohtiin löytyvät helposti Jukka Korpelan kokoamasta listasta.

Mutta mitä hyötyä tästä tiedosta sitten on? Miksi sovelluksen kehittäjän tulisi välittää asiasta? No, oikeiden otsakkeiden palautaminen voi parantaa Web-sovelluksen käytettävyyttä, turvallisuutta ja nopeutta. Kuvien ja JavaScript-tiedostojen mukana kannattaa palauttaa tieto siitä, että ne saa tallentaa välimuistiin ja pitkäksi aikaa vieläpä. Tietylle käyttäjälle henkilökohtaisten sivujen mukaan voi liittää tietojen yksityisyysasteesta riippuen sopivat otsakkeet, esimerkiksi sähköpostia tuskin kannattaa koskaan jättää välimuistiin lojumaan. Merkkikoodaus kannattaa kertoa otsakkeissa, eikä vasta meta-elementissä, ettei selaimen tarvitse arvailla mitään. Content-Disposition -otsakkeella pystyy ilmoittamaan selaimelle, että resurssi tulisi tallentaa eikä näyttää.

(Kyselyn otsakkeiden perusteella voi myös esimerkiksi valita palautettavan resurssin kielen käyttäjän selaimen asetusten perusteella ja resurssin tyypin selaimen tukemien tyyppien perusteella. Tämä on kuitenkin laajempi aihe, jossa on omat sudenkuoppansa, ja se saa siis jäädä tältä kertaa väliin.)

PHP-kehittäjät voivat käyttää header-funktiota sivun mukana lähetettävien otsakkeiden säätämiseen. Otsakkeet tulee määrätä ennen kuin mitään sivun sisältöä tulostetaan.