Universitetet i Oslo Institutt for informatikk Surfing avmystifisert i INF102 Kvile kvile@mail.com Vår 2003
Innhold 1 Vanlig surfing med GET-metoden 4 1.1 Spørringen fra klienten......................... 4 1.1.1 Websider med flere filer.................... 4 1.2 Svaret fra webserveren......................... 5 2 Sende data med FORMs 6 2.1 GET-metoden............................... 6 2.2 POST-metoden.............................. 7 3 Sesjoner og cookies 7 3.1 Cookies................................... 8 3.2 Avansert: Cookies og sikkerhet.................... 8 A Kode - En enkel webserver 9 A.1 Spørring fra en webbrowser...................... 9 Innledning Dette dokumentet er ment som en liten innføring i HTTP-protokollen 1 (HyperText Transfer Protocol) for studenter som tar INF102 ved Institutt for Informatikk, Universitetet i Oslo. Vi vil kun se på hvilke data som blir sendt fra en webbrowser 2 til en webserver og tilbake igjen. Vi skal se hva som foregår bak kulissene når vi velger en link og når vi sender over informasjon med FORMs. Det forutsettes at du har erfaring med Internett og at du kan litt om HTML og bruken av FORMs. Vi vil ikke se på hva som foregår lenger ned i arkitekturen (e.g. TCP/IP, DNS-servere). De som vil lære mer om nettverk og Internett-protokoller, kan ta kurset INF240 Datakommunikasjon. Dette dokumentet kan lastes ned fra http://www.simula.no/~jankvi/surfing.pdf. 1 En protokoll er et språk, eller et sett med regler som maskinene følger når de snakker sammen. 2 En webbrower er det programmet du bruker for å surfe på Internett, e.g. Netscape, Opera, Mozilla, lynx og Internet Explorer. 3
1 Vanlig surfing med GET-metoden Når vi surfer rundt på nettet og velger 3 en link, kan vi gå rundt til forskjellige nettsider. Men hvordan vet en webserver hvilken webside vi vil lese? 1.1 Spørringen fra klienten Når vi velger en link, sender vi en spørring til en webserver om å få et dokument. Hvis vi for eksempel velger linken <A HREF="http://www.ifi.uio.no">Insitutt for Informatikk</A> som denne HTML-koden gir oss, vil webbrowseren vår muligens sende denne minimale forespørselen til webserveren GET / HTTP/1.0 Disse to linjene er alt vi trenger å sende til en webserver for å spørre etter en webside. (Vil vil ikke se på hvordan webbrowseren finner ut hvilken webserver den skal sende spørringen til.) Den første linjen startet med metoden vi kaller, GET. Dette er den vanligste metoden for å surfe på Internett. Når vi fyller ut en FORM, vil vi ofte kalle en POST-metode i stedet. Backslashen (/) etterpå betyr at vi spør etter den siden som ligger i rota på webserveren. Hvis vi fulgte linken <A HREF="http://www.ifi.uio.no/inf102">Utvikling av datasystemer</a> kunne vi sendt denne minimale forespørselen til webserveren: GET /inf102/ HTTP/1.0 HTTP/1.0 betyr at vi bruker HTTP-protokollen, version 1.0. betyr av vi sender med en linje som det ikke står noen ting på. Når webserveren ser en slik tom linje, vet den at vi er ferdige med forespørselen vår. Ikke overraskende kan vi legge merke til at det som står inni link-tagen (mellom <A..> og </A>) ikke blir sendt til webserveren. I Appendix A kan du se hvordan du kan finne ut hva din webbrowser sender av informasjon. Den vil ganske sikkert sende over mer informasjon enn vårt minimale eksempel. 1.1.1 Websider med flere filer Mange websider inneholder referanser til andre filer. Disse filene kan for eksempel inneholde bilder, CSS (Cascade Style Sheets), Applets, lyd eller annen HTML-kode. La oss ta en enkel webside som eksempel: 3 Jeg skriver velger og ikke klikker fordi man kan surfe og velge linker på andre måten enn å bruke en mus. 4
<HTML> <HEAD> <LINK REL="stylesheet" HREF="style.css" TYPE="text/css" /> </HEAD> <BODY> <H1>Homepage</H1> <IMG SRC="topPicture.jpeg" ALT="banner" /> <P>Hello,... </P> <IMG SRC="bottomPicture.jpeg" ALT="banner" /> </BODY> </HTML> Først vil webbrowseren sende en spørring for å få siden med HTML-koden over. Så vil den for hver av referansene i HTML-koden sende en ny spørring for å få tak i de andre filer, totalt altså 4 spørringer (en for å få HTMLkoden, en for å få CSS filen (i LINK-tagen) og en sprørring for hvert av bildene). Disse spørringene vil være tilsvarende de vi har sett på. E.g. kan vi få tak i bildet toppicture.jpeg med GET /toppicture.jpeg HTTP/1.0 1.2 Svaret fra webserveren Da vet vi hvordan en spørring til en webserver ser ut, men hva sender webserveren tilbake? Vi vet at vi får en del HTML-kode. Det er denne HTMLkoden som webbrowseren vår tolker og viser fram. Men vi får også en HTTP-header (som ikke har noe med HEAD-tagen i HTML) som sier noe om hvordan forespørselen gikk, hva innholdet av svaret er og diverse annet. For å se hele svaret vi får fra webserveren, kan vi bruke et program som heter telnet. Det er et enkelt program som kan brukes for å koble seg til forskjellge servere. Vi sender med to parametere til telnet; den første er URLen (Uniform Resource Locator, eller adressen til websiden) og den andre er hvilken port vi vil koble oss på. Port 80 er standard porten hvor webservere kobler seg på for å ta imot forespørsler. Vi kjører telnet i et vanlig term-vindu og ser hva vi får. Tallene til venstre er ikke med i kjøringen, de fungerer kun som referanser. Tekst i italic er input vi skriver inn (se linje 1 og 5). 1 kvile: bash> telnet www.ifi.uio.no 80 2 Trying 129.240.64.16... 3 Connected to glitnir.ifi.uio.no. 4 Escape character is ˆ]. 5 GET / HTTP/1.0 6 7 HTTP/1.1 200 OK 8 Date: Tue, 11 Feb 2003 20:14:13 GMT 9 Server: Apache/1.3.27 (Unix) mod_perl/1.27 PHP/4.2.3 10 Last-Modified: Tue, 11 Feb 2003 20:10:02 GMT 11 Content-Length: 12124 12 ETag: "156b0-1be3-3e4959a" 5
13 Connection: close 14 Content-Type: text/html; charset=iso-8859-1 15 16 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 17 <HTML> 18 <BODY>... x </BODY> xx </HTML> På linje 1 kjører vi kommandoen telnet www.ifi.uio.no 80. Linje 2-4 er informasjon som vi får fra telnet-programmet. Webserveren er nå klar til å ta imot input fra tastaturet vårt. Vi skriver inn kallet vårt for å få nettsiden, GET / HTTP/1.0. Så trykker vi Enter for å avslutte linjen, og Enter ennå en gang for å sende en tom linje. Da vet webserveren at vi er ferdig med spørringen vår. Linje 7 og nedover er svaret vi får fra webserveren. Linje 7-14 er HTTPheaderen, etterfulgt av en blank linje (linje 15), og til slutt kommer HTTPbodyen/HTML-koden. Det er denne koden vi kan se i webbrowseren vår hvis vi velger "View Source". Linje 7 sier oss at serveren bruker HTTP-protokollen verson 1.1. 200 OK betyr at serveren forsto og behandlet spørringen korrekt. Du har kanskje iblant sett at det har stått "404 - Siden finnes ikke" når du har skrevet feil URL. Dette er tall som sier noe om hvordan spørringen vår mot serveren gikk. Date-feltet i linje 8 sier oss når spørringen ble utført. Server-feltet viser hva slags webserver som behandlet spørringen. Her ser vi at det er en Apache-server som kjører på Unix. Content-Length sier hvor lang bodyen er, i.e. hvor mange bytes selve HTML-koder er. Content-Type sier oss her at det er HTML-tekst i bodyen. Andre muligheter er e.g. image/jpeg hvis webserveren sender et JPEG-bilde. Hvilke felt webserveren sender vil variere fra webserver til webserver, både etter hva slags type det er og hvordan de er satt opp. Noen velger å ikke sende så mye informasjon av sikkerhetsmessige hensyn. Du kan jo kjøre telnet mot noen andre webservere å se hva du får. I flere webbrowsere kan man velge "View Page Info" for å få se (noe av) informasjonen i headeren. 2 Sende data med FORMs Da vet vi hvordan enkle spørriger foregår, men hvordan blir data sendt til en webserver når vi fyller ut en FORM? 2.1 GET-metoden Med GET-metoden er ting tilsvarende som med vanlig surfing. All informasjonen vi sender over er med i URLen. Vi kan tenke oss at vi fyller ut "Kvile" i INPUT-feltet i FORMen under: 6
<FORM ACTION="search.php" METHOD="get"> <INPUT NAME="searchFor" TYPE="text" /> <INPUT TYPE="submit" /> </FORM> Spørringen til webserveren blir da GET /?searchfor=kvile HTTP/1.0 Vi kunne også kalt denne metoden direkte med å skrive?searchfor=kvile på slutten av URLen. 2.2 POST-metoden POST-metoden er litt mer mystisk. La oss bruke samme FORM som i forrige avsnitt, men med METHOD satt til post. Vi vet vi sender over dataene, og at vi kan få tak i dem på serversiden med PHP-koden $searchfor = $_POST[ searchfor ]; Men hvordan blir dataene egentlig sendt? Jo, akkurat som svaret fra webserveren, så blir de sendt som en body i spørringen vår, e.g.: POST / HTTP/1.0 Content-Length: 15 searchfor=kvile Vi ser at metoden er erstattet med POST, ellers er spørringen ganske lik en GET-spørring. Forskjellen er at etter den tomme linjen følger en linje med alle dataene vi sender over. Hadde vi sendt over flere felt, kunne den siste linjen blitt searchfor=kvile&where=norway, tilsvarende hva som skjer når vi sender over flere felt med GET-metoden. 3 Sesjoner og cookies HTTP-protokollen (verson 1.0) er tilstandsløs. Det betyr at hvis vi gjør to spørringer mot en webserver, kan ikke serveren vite om vi er samme person/webbrowser som har gjort en spørring tidligere. Hver spørring vil være som om det kom fra en ny person. Men dette vet vi ikke stemmer. Når vi logger oss inn på nettbanken vår eller et annet sted hvor man må logge seg inn, så kan vi ofte gjøre flere spørringer mot webserveren etter å ha logget oss inn en gang og webserveren vet likevel at vi er oss. Dette er tilsvarene det som skjer når vi logger oss inn på websiden autentiser.php. Men hvordan kan webserveren vite at vi er oss etter at vi har logget oss på? Her brukes en teknologi som heter cookies. 7
3.1 Cookies En cookie en liten tekststreng med informasjon som lagres på klientsiden, altså i vår webbrowser. Når vi kommer til en webserver som bruker cookies, vil webserveren be oss ta vare på en cookie. Det blir gjort ved at den sender et (eller flere) cookie-felt i headeren. Denne informasjonen blir da tatt vare på hos oss, og vi sender den til webserveren hver gang vi gjør en spørring mot den 4. Ofte brukes cookies som en session-id slik at webserveren kan vite hvem vi er. Når vi skriver session_start() i PHP-koden vår, vil vi skjekke om vi har fått med en cookie-id fra webbrowseren. Hvis ikke, så lager webserveren et cookie-felt i headeren som webbrowseren vil ta vare på. Svaret fra webserveren kan da se slik ut: HTTP/1.0 200 OK Set-Cookie: id="1234567890" <HTML>... </HTML> Legg merke til Set-Cookie-feltet. Neste gang webbrowseren vår gjør et kall til webserveren vil vi sende med denne informasjonen slik: GET / HTTP/1.0 Cookie: id="1234567890" 3.2 Avansert: Cookies og sikkerhet Hvis en klient hadde fått tak i cookien til en annen klient kunne den gitt seg ut får å være den andre klienten. Heldigvis er det restriksjoner på hvem som har tilgang til hvilke cookies slik at det ikke er en triviell sak å stjele cookies/sessions. Det kan dog nevnes at de fleste/alle obligene som blir levert i INF102 vil ha sikkerhethull som gjør det mulig å stjele cookies og dermed mulighet for å gi seg ut som en annen person. Siden sikkerhet ikke er en del av kurset, trenger dere ikke å bry dere om dette, men det kan være bra å være klar over det. Du kan jo tenke på om du ser noen sikkerhetshull i oppgaven som gruppen din har levert. Siden cookies blir lagret på klientsiden, kan en webserver gjøre uønskede handlinger mot en usikker webbrowser. Dette kan være å oversvømme en webbrowser med cookies, få tilgang til cookies den ikke skal ha eller å få en klient til å oppgi sensitiv informasjon. 4 Dette er litt forenklet forklart. For det første kan vi velge om vi vil ta vare på en cookie, og vi kan velge om vi vil sende den til webserveren. Ofte tar webbrowseren seg at dette uten at vi engang vet at vi bruker cookies. 8
A Kode - En enkel webserver Her er et enkelt Java-program som vil gi oss all informasjonen som webbrowseren vår sender til en webserver. Dette Java-programmet kan lastes ned fra http://www.simula.no/~jankvi/simplewebserver.java. Etter at du har kompilert det med javac SimpleWebServer.java og startet det med java SimpleWebServer kan du bruke webbrowseren din til å åpne URLen localhost:2345 eller 127.0.0.1:2345 5. En annen interessant ting å merke seg er at programmet under faktisk er en (ekstrem simpel) webserver på under 30 linjer. import java.io.*; public class SimpleWebServer { static int port = 2345; static String reply = "HTTP/1.0 200 OK\nType: text/plain\n\n"; static void service(inputstreamreader isr, OutputStreamWriter osw) { char[] inchars = new char[1024]; try { int bytesread = isr.read(inchars, 0, 1024); // Read request. System.out.println(new String(inChars)); // Print request. osw.write(reply, 0, reply.length()); // Send the request osw.write(inchars, 0, bytesread); // back to client. osw.flush(); osw.close(); } catch (IOException e) {System.err.println(e);} } } public static void main(string args[]){ try { java.net.serversocket ss = new java.net.serversocket(port); while (true) { java.net.socket s = ss.accept(); //waiting for request service(new InputStreamReader(s.getInputStream()), new OutputStreamWriter(s.getOutputStream())); s.close(); } } catch (IOException e) {System.err.println(e);} } A.1 Spørring fra en webbrowser Etter at du har startet SimpleWebServer kan du enkelt finne ut hva din webbrowser sender av informasjon. Her kan du se spørringen som min Mozilla-webbrowser sendte når jeg ba den åpne 127.0.0.1:2345. GET / HTTP/1.1 Host: 127.0.0.1:2345 User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-us; rv:1.2) Gecko/20021204 5 127.0.0.1 er en reservert IP-adresse som betyr det samme som localhost, altså samme maskin som programmet kjører på. :2345 betyr at programmet skal snakke med port 2345, samme port som vi kjører vårt SimpleWebServer-program. 9
Accept: 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,text/css,*/*;q=0.1 Accept-Language: en-us, en;q=0.50 Accept-Encoding: gzip, deflate, compress;q=0.9 Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66 Keep-Alive: 300 Connection: keep-alive 10