Next Previous Contents

2. CGI

Det å skrive CGI-skript (Common Gateway Interface) i Ruby skiller seg ikke nevneverdig fra å skrive CGI-skript i andre språk. Skriv ut HTTP-hodelinjer (headers), hent inn CGI-variabler, generer HTML (eller noe annet interessant innhold) dynamisk og spyl det av gårde til klienten.

  1| #!/usr/bin/ruby
  2| 
  3| # Print ut HTTP-hodelinjer for å angi at vi serverer HTML.
  4| print "Content-type: text/html\r\n\r\n"
  5| 
  6| # Server litt HTML.
  7| print "<html><body><h1>Hei verden!</h1></body></html>"

Øverste linje angir hvor Ruby-fortolkeren befinner seg på serveren. /usr/bin/ruby er bare en vanlig plassering på noen Linux-varianter, når du innstallerer fra pakker. Prøv å skriv 'which ruby' om du lurer på hvor fortolkeren er på den maskinen du er på nå.

Men dette var ikke særlig spennende uten noen mulighet for å påvirke resultatet dynamisk...

2.1 Variabler

... så la oss lage en liten web-basert kalkulator.

  1| #!/usr/bin/ruby
  2| print "Content-type: text/html\r\n\r\n"
  3| print '<html><body>'   # Starter HTML-dokumentet.
  4| 
  5| require 'cgi'  # Hent inn CGI-biblioteket.
  6| cgi = CGI.new  # Lag en instans slik at vi får tak i CGI-variablene.
  7| 
  8| x = cgi['x']   # Hent CGI-variablene
  9| y = cgi['y'] 
 10| 
 11| # Skriv dem bare ut dersom vi fikk noe.
 12| if (x and x.size.nonzero?) and
 13|    (y and y.size.nonzero?) then
 14|   a = x.to_i # Gjør om til heltall.
 15|   b = y.to_i
 16|   print "#{a} multiplisert med #{b} er ", a*b
 17| end
 18| 
 19| # Skriv ut et lite skjema.
 20| print '<form>'
 21| print '<input name="x" type="text"> *'
 22| print '<input name="y" type="text"> = '
 23| print '<input type="submit" value="gange">'
 24| print '</form>'
 25| 
 26| # Avslutter HTML-dokumentet.
 27| print '</body></html>'

2.2 HTML

CGI-biblioteket kan også hjelpe deg litt med å skrive HTML-koden.

  1| #!/usr/bin/ruby
  2| require 'cgi'
  3| cgi = CGI.new('html4')
  4| cgi.out {
  5|   cgi.html {
  6|     cgi.head { 
  7|       cgi.title { 'Penere kildekode?' } 
  8|     } + 
  9|     cgi.body {
 10|       cgi.h1 { 'Gjør dette kildekoden penere?' } + 
 11|       cgi.p +
 12|       'Eller får man krøllparentes-overdose?'
 13|     }
 14|   }
 15| }

2.3 Cookies

Cookies er en måte å lagre små datamengder på maskinen til brukeren som surfer inn på sidene våre, som vi kan hente ut igjen når de kommer tilbake en annen gang.

  1| #!/usr/bin/ruby
  2| require 'cgi'
  3| c = CGI.new('html4')
  4| 
  5| # Hent ut den gamle kaken.
  6| gammel_cookie = c.cookies['rubywebnuby']
  7| 
  8| # Kurstekst i første element, antall besøk i andre element.
  9| kurs_tekst, antall_tekst = gammel_cookie
 10| antall_besok = if antall_tekst then 
 11|                  antall_tekst.to_i + 1 
 12|                else 0 end
 13| 
 14| # Lag ny kake.
 15| ny_cookie = CGI::Cookie.new('rubywebnuby',    # Kakenavn.
 16|   'Ruby Web Nuby', antall_besok.to_s          # Verdier.
 17| )
 18| 
 19| c.out( 'cookie' => [ny_cookie] ) do # Sett kaken via HTTP. 
 20|   c.html do 
 21|     c.body do
 22|       # Print ut de forrige kakene
 23|       gammel_cookie.join(c.br) + 
 24|         "<P>Du har vært her #{antall_besok} ganger før, " +
 25|         "da i forbindelse med #{kurs_tekst} kurs."
 26|     end 
 27|   end 
 28| end

Cookies er et kjekt verktøy når man ikke har noen database å lagre i, dataene er små eller brukerne er overmåte allergisk mot innloggingsskjermer. Ellers er det kanskje en ide å lagre ting på serversiden og/eller i skjulte input-elementer.

2.4 Sesjoner

Sesjoner er et overbygg over cookies, som lagrer en liten bit data i en cookie hos klienten, og (potensielt) et tonn med data på serveren.

  1| #!/usr/bin/ruby
  2| require 'cgi'
  3| require 'cgi/session'
  4| c = CGI.new('html4')
  5| sesjon = CGI::Session.new( c, 
  6|   'session_key' => 'rubywebnuby2',
  7|   'prefix' => 'ruby_sesjon.')
  8| 
  9| # Hent ut antall besøk fra sesjonen
 10| antall_tekst = sesjon['AntallBesok']
 11| antall_besok = (antall_tekst ? antall_tekst.to_i+1 : 0)
 12| 
 13| # Sett det nye antallet tilbake i sesjonen
 14| sesjon['AntallBesok'] = antall_besok
 15| 
 16| c.out do 
 17|   c.html do 
 18|     c.body do
 19|      "Du har vært her #{antall_besok} ganger før."
 20|     end 
 21|   end 
 22| end
 23| 
 24| sesjon.close # Sikre at sesjonsdata lagres på serveren.

Da har vi iallfall fått lagret en god del mer på serversiden, og høyde, alder, øyenfarge, samt en million "theme"-innstillinger for webapplikasjonen vår må ikke sendes over nettet hver gang en side hentes.

2.5 Ytelse

Til nå har vi bare kjørt disse CGI-skriptene på den trauste, trege måten. For hvert kall til sidene, må Ruby-fortolkeren startes opp og biblioteker lastes. Dette er ufattelig ineffektivt.

Vi trenger å ha minimum Ruby-fortolkeren, og helst også biblioteker, ferdig lastet og klare til dyst når en HTTP-forespørsel kommer inn. Det er flere muligheter, blant annet:

mod_ruby, WEBrick, Borges, Radical, fastcgi, IOWA, httpd, httpserv, wwwd, wwwsrv ... etc


Next Previous Contents