CGI - auf Matthias

Werbung
Netzprogrammierung:
Dynamische Web-Seiten
Robert Tolksdorf und Peter Löhr
Überblick
1.
2.
3.
4.
Dynamische Web-Inhalte
Common Gateway Interface - CGI
Formular-Verarbeitung
Servlets
Robert Tolksdorf und Peter Löhr
3
5
27
33
2
Dynamische Web-Inhalte
Robert Tolksdorf und Peter Löhr
Statische und dynamische Inhalte
• Statische Inhalte liegen vorgefertigt auf dem Server und
werden unverändert ausgeliefert und dargestellt.
• Dynamische Inhalte bewirken vor der Auslieferung und/oder
bei der Darstellung Effekte auf Inhalt oder Darstellung
durch Ausführung von Code
• ... vor der Auslieferung beim Server:
•
•
•
•
Vereinfachung der Inhaltserstellung
Erzeugung/Konvertierung von Inhalt
Anpassung/Personalisierung von Inhalt
Ergebnis anderer Berechnungen
• ... bei der Darstellung durch den Browser:
• Erzeugung einer Darstellung
• Anpassung einer Darstellung
• Interaktion mit dem Benutzer
Robert Tolksdorf und Peter Löhr
4
Common Gateway Interface - CGI
http://www.w3.org/CGI/
http://hoohoo.ncsa.uiuc.edu/cgi/overview.html
http://www.cgi101.com/
Robert Tolksdorf und Peter Löhr
Dynamische Dokumenten-Erzeugung
Merke:
Dynamische Zusammenstellung eines auszuliefernden
Dokuments durch den Server ist technisch trivial.
Beispiel:
Einflicken des aktuellen Datums in einen aus einer
Datei entnommenen HMTL-Text.
Aber:
Für jede Ressource wird spezifischer Code benötigt!
Daher:
Die URL identifiziert nicht ein vorliegendes Dokument,
sondern ein Programm, das ein Dokument erzeugt:
CGI-Programm
Robert Tolksdorf und Peter Löhr
6
Beispiel
Beispiel:
Ausgabe von Datum und Uhrzeit durch Perl-Programm date.pl
#!/usr/bin/perl
$date = localtime time;
print "Content-type: text/html\n";
# Kopfzeile
print "\n";
# Leerzeile
print "<html><head>\n";
# HTML-Text ...
print "<title>Datum</title>";
print "</head>\n";
print "<body>Heutiges Datum: $date</body>\n";
print "</html>\n";
Robert Tolksdorf und Peter Löhr
7
Voraussetzungen
• Datei date.pl enthält ein ausführbares Programm.
• Schutzstatus der Datei date.pl erlaubt die Ausführung.
• Datei liegt in demjenigen Verzeichnis, das gemäß den
Konfigurationsdaten des Servers für CGI-Programme
vorgesehen ist.
• Beispiel Apache mit Standard-Konfiguration: cgi-bin bezieht
sich auf cgi-bin oder CGI-Executables im Apache-Verzeichnis.
• Andere Konfigurationen sind möglich, vor allem für
persönliche CGI-Programme von Benutzern; das Handbuch
des jeweiligen Web Servers gibt Auskunft.
• (Dateierweiterung ist nicht festgelegt; typisch ist .cgi .)
Robert Tolksdorf und Peter Löhr
8
Funktionsweise
CGI-Prozess
HTTP-Anfrage
Web Server
CGI-Programm
HTTP-Antwort
Dokumente
CGI-Programme
Robert Tolksdorf und Peter Löhr
9
Fehlfunktion
Ein Laufzeitfehler des CGI-Programms führt zur
Fehlermeldung
500 Internal Server Error .....
die vom Browser geeignet angezeigt wird.
Robert Tolksdorf und Peter Löhr
10
CGI und Perl
Skript date.pl einfacher auch wie folgt:
#!/usr/bin/perl
$date = localtime time;
print <<EOD
Content-type: text/html
<html><head>
<title>Datum</title>
</head>
<body>Heutiges Datum: $date</body>
</html>
EOD
CGI mit Perl:
http://www.cs.tut.fi/~jkorpela/perl/cgi.html
Robert Tolksdorf und Peter Löhr
11
Alternativen für Skript date.pl
• Skript date.cgi als Alternative für date.pl:
#!/bin/sh
echo Content-type: text/html
echo
echo "<html><head>"
echo "<title>Datum</title>"
echo "</head><body>"
echo Heutiges Datum:
date
echo "</body></html>“
• Programm date als Alternative - mit folgendem Quellcode:
#include <time.h>
main() {
printf("Content-type: text/html\n\n");
printf("<html><head><title>Datum</title></head>");
printf("<body>Heutiges Datum: ");
time_t now; time(&now);
printf("%s", ctime(&now));
printf("</body></html>\n");
}
Robert Tolksdorf und Peter Löhr
12
Eingabe für CGI-Programme ...
Eingabe wird mit Trennzeichen ? an den URL angehängt, z.B.
http://www.dot.com/cgi-bin/oracle?querystring
und steht dem CGI-Programm in der Umgebungsvariablen
QUERY_STRING als Zeichenkette zur Verfügung.
Beispiel:
Robert Tolksdorf und Peter Löhr
13
URL-Codierung der Eingabe
Die auf ? folgende Eingabe wird für die Übertragung
URL-codiert, damit bedeutungstragende Zeichen wie
=, &, ... übertragen werden können:
Leerzeichen -> +
& -> %26
@ -> %40
etc.
Beispiel: %&" "+#äß -> %25%26%22+%22%2B%23%E4%DF
Medientyp der Nachricht ist application/x-www-form-urlencoded.
Robert Tolksdorf und Peter Löhr
14
URL-Codierung in Java
• java.net.URLEncoder:
• public static String encode(String s, String enc) throws
UnsupportedEncodingException
• enc ist registrierte Zeichensatzbenennung wie “ISO-8859-1“
• java.net.URLDecoder:
• public static String decode(String s, String enc) throws
UnsupportedEncodingException
Robert Tolksdorf und Peter Löhr
15
... und hinter den Kulissen ...
Eine von vielen Möglichkeiten für die Datei echo:
#!/bin/sh
cd /Users/lohr/fu/lehre/alp5/WS-08/code/cgi
java Echo $QUERY_STRING
mit
import java.io.*;
public class Echo {
public static void main (String arg[]) throws IOException {
String message = arg[0];
String answer = message.replace('i','o');
System.out.println("Content-type: text/html");
System.out.println();
System.out.println("<html>");
System.out.println("<head><title>Echo</title></head><body>");
System.out.println("<br><b>Ruf war: </b>" + message + "<br>");
System.out.println("<br><b>Echo ist: </b>“ + answer + "<br>");
System.out.println("</body></html>");
}
}
Robert Tolksdorf und Peter Löhr
16
... passiert dies
• Web Server erhält
GET /cgi-bin/echo?igittigitt HTTP/1.1
Accept-Language: de-de
Accept-Encoding: gzip, deflate
.......
• ... und startet Prozess mit QUERY_STRING = igittigitt
und CGI-Programm echo.
• Problematisch: die Eingabe ist völlig unstrukturiert;
der Server weiß nichts von eventuell mehreren in der
Eingabe enthaltenen Parametern noch von deren Typen.
Die Zeichenkette wird unbesehen an das CGI-Programm
weitergegeben.
Robert Tolksdorf und Peter Löhr
17
Umgebungsvariable des CGI
• Die Schnittstelle CGI - Common Gateway Interface -
zwischen Web Server und CGI-Programm wird durch
einen festgelegten Satz von Umgebungsvariablen
bestimmt.
• Shell: $QUERY_STRING, $REQUEST_METHOD, .....
• Perl: die vordefinierte Variable $ENV ist die Tabelle aller
Umgebungsvariablen mit ihren Werten. Beispiel:
#!/usr/bin/perl
print "Content-type: text/html\n";
# Kopfzeile
print "\n";
# Leerzeile
print "<html><head>";
# HTML-Text
print "<title>Ich erkenne Sie</title>";
print "</head>";
print "<body>Sie benutzen diesen Browser:<br>";
print $ENV{"HTTP_USER_AGENT"};
print "</body></html>";
Robert Tolksdorf und Peter Löhr
18
Umgebungsvariable
• SERVER_NAME
•
•
•
•
•
•
•
Der Name des Servers, wie er in der URL des CGI-Programms
auftritt.
SERVER_PORT
Die Nummer des Ports, über den die Anfrage geschickt wurde.
SERVER_PROTOCOL
Das Protokoll, mit dem die Anfrage geschickt wurde, als
Zeichenkette der Form Protokoll/Version. Z.B. HTTP/1.1
SERVER_SOFTWARE
Server, der das CGI-Programm startet, als metaName/Version.
Beispiel: NCSA/1.4.2.
GATEWAY_INTERFACE
Version der CGI-Spezifikation, der der Server folgt, als CGI/Version.
Z.B.: CGI/1.1.
REQUEST_METHOD
Methode, die bei der Anfrage verwendet wurde: GET oder POST (s.u.)
SCRIPT_URI
Vollständiger URI des CGI-Programms
SCRIPT_NAME
Der Name des CGI-Programms in der URI, z.B. /cgi-bin/env.cgi
Robert Tolksdorf und Peter Löhr
19
Umgebungsvariable
• QUERY_STRING
•
•
•
•
•
•
•
•
Die Eingabe/Anfrage an das CGI-Programm
REMOTE_HOST
Der Name des Rechners, von dem die Anfrage kam
REMOTE_ADDR
Die Internetadresse des Rechners, von dem die Anfrage kam
REMOTE_USER
Der Benutzername, für den das Passwort eingegeben wurde
REMOTE_IDENT
Benutzerkennung des anfordernden Benutzers, falls ermittelbar
AUTH_TYPE
Name des Verfahrens, mit dem das Passwort kodiert ist
CONTENT_TYPE
Bei Verwendung der POST-Methode steht hier der Medientyp des Inhalts,
der an der Standardeingabe gelesen werden kann
CONTENT_LENGTH
Die Länge des Inhalts bei der POST-Methode
HTTP_ACCEPT
Die Medienarten, die der Browser akzeptieren will
Robert Tolksdorf und Peter Löhr
20
Umgebungsvariable
• Eventuell gibt es auch andere Variable, abhängig vom Server.
• Ein kleines Skript env.cgi zur Ermittlung aller Variablen:
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
foreach $var (sort keys %ENV) {
$val = $ENV{$var};
print "$var = $val\n";
}
Test:
Robert Tolksdorf und Peter Löhr
21
Umgebungsvariable
Robert Tolksdorf und Peter Löhr
22
CGI, Perl und HTML
#!/usr/bin/perl
use CGI;
$cgi = new CGI;
print $cgi->header(),
$cgi->start_html('Echo'),
$cgi->h3('Echo der Eingabe:'),
$cgi->pre($ENV{'QUERY_STRING'}),
$cgi->end_html();
(Hilfreich ist wiederum http://www.cs.tut.fi/~jkorpela/perl/cgi.html )
Robert Tolksdorf und Peter Löhr
23
Standardeingabe des CGI-Programms
• Wird für die Anfrage die Methode POST statt GET
verwendet, so wird der Inhalt der Anfrage nicht über
QUERY_STRING, sondern über die Standardeingabe
vermittelt.
• Ein einfaches Perl-Skript echo.cgi, das sowohl mit GET
als auch mit POST aufgerufen werden kann:
#!/usr/bin/perl
print "Content-type: text/plain\n"; # Kopfzeile
print "\n";
# Leerzeile
$method = $ENV{'REQUEST_METHOD'};
if
($method eq "GET") { $buffer = $ENV{'QUERY_STRING'}; }
elsif ($method eq "POST") {read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}
print $buffer;
Robert Tolksdorf und Peter Löhr
24
Standardausgabe des CGI-Programms
• Ausgaben des CGI-Programms über StandardausgabeKanal werden als Antwort an den Klienten geschickt.
• Notwendig: Content-Type-Kopfzeile
• Möglich: Beliebige Medienarten, z.B. auch Bilder
• Beispiel Postscript:
(http://www.ntecs.de/old-hp/uu9r/lang/html/postscript.de.html)
#!/usr/bin/perl
print "Content-type: application/postscript\n\n";
print <<EOD
%!PS-Adobe-4.0
/Courier findfont
20 scalefont
setfont
50 700 moveto
(Dies ist ein Postscript-Dokument.) show
showpage
EOD
Robert Tolksdorf und Peter Löhr
25
CGI bei www.inf.fu-berlin.de
• Ihre Homepage hat die URL
•
http://www.inf.fu-berlin.de/~<benutzer>
Im Dateisystem bei
• UNIX: /web/page.mi.fu-berlin.de/web-home/<benutzer>
• Windows: \\web.mi.fu-berlin.de\page.mi.fu-berlin.de\<benutzer>
• Darin gibt es zwei Verzeichnisse
• …/<benutzer>/public_html
• Ihr Webspace mit index.html als Startseite, von außen sichtbar
• Skripte können nicht darin schreiben
• …/<benutzer>/data-rw
• von außen nicht sichtbar
• Skripte können darin schreiben
• Ein eigenes CGI-Programm, z.B. /web/page.mi.fu-berlin.de/
•
web-home/lohr/public_html/cgi-bin/example.cgi
mit URL http://www.inf.fu-berlin.de/~lohr/cgi-bin/example.cgi
wird mit der Autorisierung des Eigners (hier lohr) ausgeführt!
Details: https://www.mi.fu-berlin.de/w/Tec/UserPages
Robert Tolksdorf und Peter Löhr
26
Formular-Verarbeitung
http://www.w3.org/TR/html401/interact/forms.html
http://www.w3schools.com/html/html_forms.asp
Robert Tolksdorf und Peter Löhr
Formular wird ausgefüllt
Ein Web-Formular:
(oder Eingabe-Taste)
Robert Tolksdorf und Peter Löhr
28
Ergebnis des Formularverarbeitung
Effekt: ein CGI-Programm wird gestartet:
Der QUERY_STRING ist URL-codiert (siehe S. 14),
d.h. mit Ersetzung gewisser Sonderzeichen durch andere:
firstname=Adam+W.&lastname=Smith&age=23
&email=smith%40inf.fu-berlin.de&sex=Male
Robert Tolksdorf und Peter Löhr
29
Das Formular in HTML
Datei gothic.html:
<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<HTML><TITLE>Welcome to the Gothic Club</TITLE>
<h2>Welcome to the Gothic Club!</h2>
Check your eligibility for membership:<br><br>
<FORM action="http://localhost/cgi-bin/alp5/gothic.cgi" method="GET">
First name:<INPUT type="text" name="firstname" size=10>
Last name:<INPUT type="text" name="lastname"><br>
Age:
<INPUT type="text" name="age" size=2><br>
email:
<INPUT type="text" name="email"><br>
Sex:
<INPUT type="radio" name="sex" value="Male"> male
<INPUT type="radio" name="sex" value="Female"> female
<br><br>
<INPUT type="submit" value="Send"> <INPUT type="reset">
</FORM>
</HTML>
Übung: geeignetes gothic.cgi schreiben!
(-> http://hoohoo.ncsa.uiuc.edu/cgi/forms.html
http://www.cs.tut.fi/~jkorpela/perl/cgi.html )
Robert Tolksdorf und Peter Löhr
30
Formulare, Perl und HTML
Echo einer Eingabe (vergleiche mit S. 23):
#!/usr/bin/perl
use CGI;
$cgi = new CGI;
print $cgi->header(),
$cgi->start_html('Echo'),
$cgi->h3('Echo der Eingabe:'),
$cgi->pre($cgi->param('Eingabe')),
$cgi->end_html();
Robert Tolksdorf und Peter Löhr
31
... und mit POST statt GET
Datei gothic.html:
<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<HTML><TITLE>Welcome to the Gothic Club</TITLE>
<h2>Welcome to the Gothic Club!</h2>
Check your eligibility for membership:<br><br>
<FORM action="http://localhost/cgi-bin/alp5/gothic.cgi" method="POST">
First name:<INPUT type="text" name="firstname" size=10>
Last name:<INPUT type="text" name="lastname"><br>
Age:
<INPUT type="text" name="age" size=2><br>
email:
<INPUT type="text" name="email"><br>
Sex:
<INPUT type="radio" name="sex" value="Male"> male
<INPUT type="radio" name="sex" value="Female"> female
<br><br>
<INPUT type="submit" value="Send"> <INPUT type="reset">
</FORM>
</HTML>
... denn das CGI-Programm erhält die Daten über die Standardeingabe.
Robert Tolksdorf und Peter Löhr
32
Java Servlets
http://java.sun.com/javaee/5/docs/api/javax/servlet/package-summary.html
Robert Tolksdorf und Peter Löhr
Servlets
• Servlets:
• CGI-Programme können in Java geschrieben werden (s.S.12)
• Wenn der Web Server selber auf einer JVM läuft - kann er
dann nicht einfach eine „Java-CGI-Komponente“ in einem
Thread ausführen anstatt einen schwergewichtigen Prozess
zu erzeugen?
• Ja - Java Servlets sind solche Komponenten.
• Unterschiede zu CGI (und Applets):
• Ein/Ausgabe läuft nicht über Umgebungsvariable bzw.
Standard-Ein/Ausgabe, sondern über Java-Schnittstelle
• Servlets als Komponente in JVM eines Servers geladen
• (Applets als Komponente in JVM eines Browsers geladen)
• Schnittstelle:
• Erweitern der Klasse javax.servlet.http.HttpServlet
• Überschreiben von doGet bzw. doPost
Robert Tolksdorf und Peter Löhr
34
Beispiel Gothic Club
Statt gothic.cgi wird folgende Klasse bereitgestellt:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class GothicServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res )
throws ServletException, IOException {
String sex = req.getParameter("sex");
String age = req.getParameter("age");
boolean eligible =
sex=="Male" && age.compareTo("70")>0 ||
sex=="Female" && age.compareTo("75")>0;
String firstname = req.getParameter("firstname");
...
Robert Tolksdorf und Peter Löhr
35
Beispiel Gothic Club
...
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("<html>");
out.println("<head><title>Reply</title></head>");
out.println("<body>");
if (!eligible) {
out.println("<br><i>Sorry</i>, ");
out.println(firstname.split(" ")[0]);
out.println(", you are not eligible."); }
else .....
out.println("</body>");
out.println("</html>");
}
}
Robert Tolksdorf und Peter Löhr
36
Eingabe
• Über das HttpServletRequest-Objekt kann man die
angelieferten Daten komfortabler als mit einem CGIProgramm erfragen, z.B.
• getRemoteHost()
• getMethod()
• getServletPath()
GET oder POST oder ...
• Query-String
• getQueryString()
• getParameter(String name)
• getParameterValues(String name)
evtl. null
evtl. null
evtl. null
• Kopfzeilen
• getHeaderNames()
• getHeader(String name)
Robert Tolksdorf und Peter Löhr
evtl. null
37
Ausgabe
• Über das HttpServletResponse-Objekt können Statuscode
und Kopfzeilen komfortabel gesetzt werden, z.B.
• setStatus(int sc)
• setHeader(String name, String value)
• setContentType(String ct)
• ... oder fertige Antworten geschickt werden, z.B.
• sendError(int sc)
• Konfiguration von Servlets (z.B. Bindung eines ServletObjekts an ein URL):
Siehe entsprechenden Webserver
• Apache tomcat: http://tomcat.apache.org/
Robert Tolksdorf und Peter Löhr
38
Einschlägige Web Server
• Achtung:
nur Java-basierte Web Server verfügen über einen
Container für Servlets! („Web/Servlet Container“)
und unterstützen damit das Servlet-Konzept.
• Unterstützung von Servlets:
• Sun Java System Web Server http://www.sun.com/software/products/web_srvr/
• Apache Tomcat - http://tomcat.apache.org
• JBoss - http://www.jboss.com (verschiedene Plattformen)
• .....
• Keine Unterstützung von Servlets:
• Apache HTTP Server - http://httpd.apache.org
• AOLServer - http://aolserver.sourceforge.net
• MS IIS - http://www.iis.net
Robert Tolksdorf und Peter Löhr
39
Servlets versus CGI
• Portabilität
• CGI führt weitere Sprache ein, oft extra Bibliothek nötig.
• Servlets sind Teil der Java-Welt und sind sauberer
strukturiert.
• Leistungspotential
• CGI ist eine isolierte Ad-hoc-Lösung für beim Server
generierte dynamische Inhalte.
• Servlets haben Anschluss an die gesamte Java-Welt,
einschließlich Sicherheitsarchitektur.
• Effizienz
• Für die Ausführung eines CGI-Programms wird jedes Mal
ein neuer Prozess gestartet.
(Ausnahme: FastCGI-Mechanismus).
• Servlets bleiben in der JVM geladen.
Robert Tolksdorf und Peter Löhr
40
Zusammenfassung
• CGI
• Dynamische Erzeugung von Inhalten durch CGI-Programme
• Beliebige Sprache - verbreitet sind Skript-Sprachen
• Skriptsprachen wie Perl u.a. vereinfachen die Erzeugung
von HTML
• Formularverarbeitung
• Parameterübergabe vom Klienten an den CGI-Prozess über
Umgebungsvariable (GET) oder Standardeingabe (POST)
• Skriptsprachen wie Perl u.a. vereinfachen die Entnahme der
Parameter aus dem query string.
• Servlets
• Rahmenwerk für „CGI-ähnliche Komponenten“ in Java
• Threads anstelle schwergewichtiger Prozesse
• Ein/Ausgabe über komfortable Schnittstellen
Robert Tolksdorf und Peter Löhr
41
Literatur
• Heiko Wöhr: Web-Technologien. dpunkt 2004.
• CGI Specification:
• http://www.w3.org/CGI
• http://hoohoo.ncsa.uiuc.edu/cgi
• http://www.cgi101.com
• Formularverarbeitung:
•
• http://www.w3.org/TR/html401/interact/forms.html
• http://www.w3schools.com/html/html_forms.asp
Servlets: http://java.sun.com/
javaee/5/docs/api/javax/servlet/package-summary.html
• ... und etliche Bücher zu speziellen Themen (CGI etc.)
Robert Tolksdorf und Peter Löhr
42
Herunterladen