import - auf Matthias

Transcription

import - auf Matthias
Netzprogrammierung:
URL-Schemata
Robert Tolksdorf und Peter Löhr
Überblick
1. Vereinheitlichte Dienstnutzung in Java
2. Eigene URL-Schemata
3. Push- und Pull-Interaktion
Robert Tolksdorf und Peter Löhr
3
24
28
2
Vereinheitlichte Dienstnutzung in Java
Robert Tolksdorf und Peter Löhr
URI, URL, URN
• Uniform Resource Identifier - URI: „ ..... is a compact string
of characters for identifying an abstract or physical resource“
[RFC 2396]
• Syntax:
• absoluteURI = scheme ":" .....
• relativeURI = .....
• .....
• Beispiele:
•
•
•
•
•
•
•
ftp://ftp.is.co.za/rfc/rfc1808.txt
gopher://spinaltap.micro.umn.edu/00/Weather/Los%20Angeles
http://www.math.uio.no/faq/compression-faq/part1.html
mailto:mduerst@ifi.unizh.ch
news:comp.infosystems.www.servers.unix
file:/users/lohr/tmp/abc
urn:isbn:n-nn-nnnnnn-n
• URI-Schema (scheme) typisiert URIs (ftp, gopher, fax, file,…)
Robert Tolksdorf und Peter Löhr
4
URI, URL, URN
• Uniform Resource Locator - URL: „ ... is a compact
string representation for a resource available via the
Internet.“ [RFC 1738]
• URL ist ein URI, dessen Schema auf die Zugreifbarkeit der
Ressource im Netz hinweist,
• z.B. ftp://ftp.is.co.za/rfc/rfc1808.txt
• Uniform Resource Name - URN: „ ... are intended to
serve as persistent, location-independent, resource
identifiers and are designed to make it easy to map
other namespaces into URN-space“ [RFC 2141]
•
•
•
•
Syntax: URN = "urn:" nameSpaceIdentifier ":" string
z.B. urn:isbn:n-nn-nnnnnn-n
Ist eher URI, der Eigenschaft der Resource beschreibt
URN-Namensraum strukturiert URNs (isbn, issn, ...)
Robert Tolksdorf und Peter Löhr
5
URL
• URL-Schemata sind für Internet-Dienste definiert und
vereinheitlichen damit deren Nutzung syntaktisch:
• http://grunge.cs.tu-berlin.de:8000/
• ftp://ftp.cs.tu-berlin.de/pub/net/www
• mailto:tolk@inf.fu-berlin.de
• Form:
http://grunge.cs.tu-berlin.de:8000/res/data.html#top
Protokoll
Rechnername
Portnummer
Pfad
Stelle
Ressource
• Für URLs ist nur die Syntax definiert; die Semantik
hängt vom Schema ab (das durch ein Protokoll
umgesetzt wird).
Robert Tolksdorf und Peter Löhr
6
java.net.URL
• URLs als Objekte der Java-klasse java.net.URL
• Konstruktoren:
• Aus Zeichenkette:
• URL(String spec)
• Aus Komponenten:
• URL(String protocol, String host, String file)
• URL(String protocol, String host, int port, String file)
• Relativ zu anderer URL
• URL(URL context, String spec)
• Mit eigenem Protokollobjekt
• URL(String protocol, String host, int port,
String file, URLStreamHandler handler)
• URL(URL context, String spec,
URLStreamHandler handler)
Robert Tolksdorf und Peter Löhr
7
java.net.URL
• Bestandteile erfragen:
•
•
•
•
•
•
•
•
•
String
String
String
String
int
String
String
String
String
getAuthority()
getFile()
getHost()
getPath()
getPort()
getProtocol()
getQuery()
getRef()
getUserInfo()
• Vergleichen:
• boolean equals(Object obj)
• boolean sameFile(URL other)
• Darstellung als Zeichenkette
• String
toString()
Robert Tolksdorf und Peter Löhr
8
... und zur Abwechslung mal Perl
$ cat uri
#!/usr/bin/perl
use URI;
$url = URI->new($ARGV[0]);
print "Scheme: ", $url->scheme( ), "\n";
print "Userinfo: ", $url->userinfo( ), "\n";
print "Hostname: ", $url->host( ), "\n";
print "Port: ", $url->port( ), "\n";
print "Path: ", $url->path( ), "\n";
print "Query: ", $url->query( ), "\n";
$ uri http://www.cnn.com:mainpage@129.170.213.101:80/research.php
Scheme: http
Userinfo: www.cnn.com:mainpage
Nicht Bestandteil der HTTP_
Hostname: 129.170.213.101
Spezifikation, aber von vielen
Port: 80
Browsern akzeptiert (und meist
Path: /research.php
ignoriert) (Sicherheitsrisiko!)
Query:
$
Robert Tolksdorf und Peter Löhr
9
URLConnection
• Man kann sich über eine „Verbindung“ zu einer durch
eine URL bezeichnete Ressource „verbinden“:
• URLConnection openConnection()
• Das für das Schema zuständige Protokoll muss
implementiert sein; Prüfung (Unix):
currentjdk/classes $ jar tf classes.jar | grep URLConnection.class
sun/net/www/protocol/ftp/FtpURLConnection.class
sun/net/www/protocol/gopher/GopherURLConnection.class
sun/net/www/protocol/http/HttpURLConnection.class
sun/net/www/protocol/mailto/MailToURLConnection.class
java/net/HttpURLConnection.class
sun/net/www/protocol/jar/JarURLConnection.class
java/net/JarURLConnection.class
sun/net/www/protocol/file/FileURLConnection.class
sun/net/www/URLConnection.class
java/net/URLConnection.class
currentjdk/classes $
Robert Tolksdorf und Peter Löhr
10
Beispiel: Dateien lesen ...
import java.net.*;
import java.io.*;
public class GetFile {
public static void main(String[] argv) throws IOException {
URL url = new URL(argv[0]);
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(new
InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null)
System.out.println(line);
in.close();
}
}
Robert Tolksdorf und Peter Löhr
11
... mit Schema http:
$ java GetFile http://www.mi.fu-berlin.de/~lohr/advent.txt
Es treibt der Wind im Winterwalde
die Flockenherde wie ein Hirt,
und manche Tanne ahnt, wie balde
sie fromm und lichterheilig wird,
und lauscht hinaus. Den wei?en Wegen
streckt sie die Zweige hin ? bereit,
und wehrt dem Wind und w?chst entgegen
der einen Nacht der Herrlichkeit.
(Rilke)
$
Robert Tolksdorf und Peter Löhr
12
... mit Schema ftp:
$ java GetFile
drwxrwxr-x
drwsr-xr-x
drwx-----drwxrws--drwxrws--drwxr-xr-x
drwxrwxr-t
ftp://ftp.inf.fu-berlin.de
4 ftp ftp
4096 Oct 26 04:05
2 ftp ftp
4096 Feb 8 2008
2 ftp ftp
4096 Oct 27 2005
2 ftp ftp
4096 Oct 20 21:16
2 ftp ftp
4096 May 30 2008
2 ftp ftp
4096 Aug 2 2007
50 ftp ftp
4096 Oct 7 14:47
incoming
log
lost+found
mathfilm2008
mevis
msgs
pub
$ java GetFile ftp://ftp.inf.fu-berlin.de/pub/readme
This is only a local File-Hierarchy of 'math.fu-berlin.de' !
====
For public-domain Software and other unspecific
Information use server 'ftp.fu-berlin.de'
(do anonymous ftp at ftp.fu-berlin.de. ...........
...........................
$
Robert Tolksdorf und Peter Löhr
13
... mit Schema file:
Der Effekt von cat uri wird auch erzielt mit
$ java GetFile file:/users/lohr/tmp/uri
#!/usr/bin/perl
use URI;
$url = URI->new($ARGV[0]);
print "Scheme: ", $url->scheme( ), "\n";
print "Userinfo: ", $url->userinfo( ), "\n";
print "Hostname: ", $url->host( ), "\n";
print "Port: ", $url->port( ), "\n";
print "Path: ", $url->path( ), "\n";
print "Query: ", $url->query( ), "\n";
$
(Warum einfach, wenn es auch kompliziert geht! ;-)
Robert Tolksdorf und Peter Löhr
14
Datei schreiben mit Schema ftp:
import java.net.*;
import java.io.*;
public class PutFile {
public static void main(String[] argv) throws IOException {
URL url = new URL("ftp://ftp.inf.fu-berlin.de/incoming/lohrfile");
URLConnection connection = url.openConnection();
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.println("Vom Eise befreit sind Strom und Bäche");
out.close();
}
}
$ java PutFile
$ java GetFile ftp://ftp.inf.fu-berlin.de/incoming/
drwxr-xr-x
2 ftp
ftp
4096 Jul 6 03:05
kia
-rw-r--r-1 ftp
ftp
38 Dec 12 07:56
lohrfile
drwxrwx--2 ftp
ftp
4096 Sep 29 12:45 tcimage
$
Robert Tolksdorf und Peter Löhr
15
java.net.URLConnection
• Zustände von URLConnection
• nicht verbunden
• verbunden
• geschlossen
• connect() wechselt von nicht verbunden zu verbunden,
falls noch nicht verbunden.
• Einige Methoden, die eine Verbindung brauchen,
wechseln implizit zu verbunden (getInputStream, ... )
Robert Tolksdorf und Peter Löhr
16
java.net.URLConnection
• Abfragen der Eigenschaften der Ressource
•
•
•
•
Object getContent() (z.B. Eingabestrom-Objekt)
String getHeaderField(String name)
InputStream getInputStream()
OutputStream getOutputStream()
• Übliche Kopfzeilen-Information
•
•
•
•
•
•
getContentEncoding() (Kompression)
getContentLength()
getContentType()
(MIME-Typ und Zeichensatz)
getDate()
getExpiration()
getLastModifed()
• ... sind unter Umständen errechnet oder leer
Robert Tolksdorf und Peter Löhr
17
Informationen über eine Seite holen
import java.net.*;
import java.io.*;
public class GetInfo {
public static void main(String[] argv) throws Exception{
URL page = new URL(argv[0]);
URLConnection connection = page.openConnection();
System.out.println("Länge: " +connection.getContentLength());
System.out.println("Typ: "
+connection.getContentType());
System.out.println("Klasse:\n"+connection.getContent().getClass());
}
}
$ java GetInfo http://www.inf.fu-berlin.de
L?nge: 23761
Typ: text/html; charset=utf-8
Klasse:
class sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
$
Robert Tolksdorf und Peter Löhr
18
Informationen über eine Seite holen
$ java GetInfo http://www.mi.fu-berlin.de/~lohr/classes/echo/Factory.class
L?nge: 227
Typ: application/x-java-vm
Klasse:
class sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
$ java GetInfo http://www.inf.fu-berlin.de/styles/inst-title-600x400.jpg
L?nge: 11947
Typ: image/jpeg
Klasse:
class sun.awt.image.URLImageSource
$
$ java GetInfo ftp://ftp.ietf.org
L?nge: -1
Typ: content/unknown
Klasse:
class sun.net.www.protocol.ftp.FtpURLConnection$FtpInputStream
$
Robert Tolksdorf und Peter Löhr
19
java.net.URLConnection
• Setzen von Eigenschaften der Anfrage
• setAllowUserInteraction(boolean b)
Anfrage findet in Interaktion mit dem Benutzer statt
• setDoInput(boolean b)
Klient will von Verbindung lesen (Voreinstellung: true)
• setDoOutput(boolean b)
Klient will auf Verbindung schreiben (Voreinstellung: false)
• setIfModifiedSince(String s)
IfModifiedSince-Kopfzeile setzen
• setUseCaches(boolean b)
Zwischenspeichern von Daten erlauben (Voreinstellung: true)
• setRequestProperty(String key, String value)
Kopfzeile setzen
Robert Tolksdorf und Peter Löhr
20
Beispiel: Sprache einstellen
import java.net.*;
import java.io.*;
public class GetInfoLang {
public static void main(String[] argv) throws Exception{
URL page=new URL(argv[0]);
URLConnection connection=page.openConnection();
if (argv.length == 2)
connection.setRequestProperty("Accept-Language",argv[1]);
System.out.println("Laenge: "+connection.getContentLength());
System.out.println("Typ: "+connection.getContentType());
System.out.println("Klasse:\n"+connection.getContent().getClass());
}
}
Robert Tolksdorf und Peter Löhr
21
Eine mehrsprachige Website
$ java GetInfoLang http://www.cs.tut.fi/~jkorpela/multi
Laenge: 1848
Typ: text/html
Klasse:
class sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
$ java GetInfoLang http://www.cs.tut.fi/~jkorpela/multi en
Laenge: 1878
Typ: text/html
.../index-en.htm !
Klasse:
class sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
$ java GetInfoLang http://www.cs.tut.fi/~jkorpela/multi de
Laenge: 2433
Typ: text/html
.../index-de.htm !
Klasse:
class sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
Robert Tolksdorf und Peter Löhr
22
Eigene URL-Schemata
Robert Tolksdorf und Peter Löhr
Eigene URL-Schemata
• URL-System in Java ist um neue Schemata erweiterbar.
Beispiel: daytime (für den Internet-Dienst auf Port 13).
• Dazu müssen definiert werden
• eine Klasse DaytimeURLConnection extends URLConnection
• eine Klasse Handler extends URLStreamHandler
• Sie müssen in einem Paket stehen, z.B. in
package mypacks.daytime
• Durch die Property java.protocol.handler.pkgs muss dem
Laufzeitsystem mitgeteilt werden, wo die eigenen Klassen
stehen:
$ java -Djava.protocol.handler.pkgs=mypacks \
GetInfo daytime://localhost
Robert Tolksdorf und Peter Löhr
24
Daytime URLs
package mypacks.daytime;
import java.net.*;
import java.io.*;
public class DaytimeURLConnection extends URLConnection {
Socket socket;
public DaytimeURLConnection(URL url) { super(url); }
public void connect() throws IOException {
socket = new Socket(url.getHost(), 13);
}
public Object getContent() throws IOException {
connect();
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
return in.readLine();
}
}
Robert Tolksdorf und Peter Löhr
25
Daytime URLs
package mypacks.daytime;
import java.net.*;
public class Handler extends URLStreamHandler{
protected URLConnection openConnection(URL u) {
return new DaytimeURLConnection(u);
}
}
$ java -Djava.protocol.handler.pkgs=mypacks \
GetInfo daytime://localhost
12 DEC 2008 16:15:06 CET
$
Robert Tolksdorf und Peter Löhr
26
Push- und Pull-Interaktion
Robert Tolksdorf und Peter Löhr
Client-Pull und Server-Push
• HTTP-Interaktion mit Anfrage und Antwort wird durch
Client-Pull und Server-Push erweitert:
• Client-Pull
• Klient lädt Inhalte in regelmäßigen Abständen nach
• Server löst das Verhalten durch zusätzliche Kopfzeile aus
• Server-Push
• Anbieter schickt mehrere Antworten nacheinander
• Klient ersetzt jeweils die Darstellung
Robert Tolksdorf und Peter Löhr
28
Client-Pull
• Server gibt in der Antwort zusätzliche Kopfzeile an:
• Refresh: seconds; .....
• Beispiel:
• Refresh: 60;
• Korrekter Browser nimmt das zur Kenntnis und lädt
regelmäßig die Seite nach.
Robert Tolksdorf und Peter Löhr
29
Beispiel: Dynamische Zeitanzeige
import java.net.*; import java.io.*;
public class TimeServer {
public static void main(String[] argv) throws Exception {
ServerSocket ss= new ServerSocket(Integer.parseInt(argv[0]));
while (true) {
Socket socket=ss.accept();
(new BufferedReader(
// Kopfzeile lesen - und ignorieren
new InputStreamReader(
socket.getInputStream()))).readLine();
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println("HTTP/1.1 200 Ok\n"+
"Content-type: text/html\n"+
"Refresh: 1;\n\n"+
"<html><head><title>Date</title></head>\n"+
"<body><p>Es ist hier gerade "+
new java.util.Date()+
"</body></html>\n");
out.flush();
socket.close(); }
}}
Testen mit Browser!
Robert Tolksdorf und Peter Löhr
30
Server-Push
• Anbieter liefert eine Antwort vom Medientyp multipart/mixed an den
•
•
•
Klienten
Markierung trennt mehrere vollständigen Antwortteile
Klient ersetzt Darstellung durch jeweils neuen Antwortteil
Server verzögert Auslieferung von jedem Antwortteil:
HTTP/1.1 200 Ok
Content-type: multipart/mixed;boundary=meinSeitenwechsel
--meinSeitenwechsel
Content-type: text/html
<html><head><title>Ping</title></head><body>
<h2>PING!</h2></body></html>
(Pause)
--meinSeitenwechsel
Content-type: text/html
<html><head><title>Pong</title></head><body>
<h2>PONG!</h2></body></html>
Robert Tolksdorf und Peter Löhr
31
Server-Push
import java.net.*;
import java.io.*;
import java.util.*;
public class ServerPush {
public static void main(String[] argv) throws Exception {
int port = Integer.parseInt(argv[0]);
int pause = 1000 * (argv.length<2 ? 1 : Integer.parseInt(argv[1]));
ServerSocket s = new ServerSocket(port);
while (true) {
Socket socket = s.accept(); //nix lesen!
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(
"HTTP/1.1 200 Ok\n“ +
"Content-type: multipart/mixed; boundary=Seite\n");
.....
Robert Tolksdorf und Peter Löhr
32
Server-Push
}
}
.....
while (!out.checkError()) {
out.println("--Seite\nContent-type: text/html\n");
out.println(
"<html><head>" +
"<title>Date</title></head>\n" +
"<body><p><br>" +
"Es ist hier gerade " + new Date() +
"</body></html>\n");
out.flush();
Thread.sleep(pause);
}
out.println("\n--Seite--\n");
socket.close();
}
Testen z.B. mit Firefox (nicht Safari!)
Robert Tolksdorf und Peter Löhr
33
Literatur
• www.ietf.org
• T. Berners-Lee, R. Fielding, L. Masinter. Uniform Resource
•
•
•
•
•
Identifiers (URI): Generic Syntax. RFC 2396. 1998
Berners-Lee, T., Masinter, L., and M. McCahill, Editors.
Uniform Resource Locators (URL), RFC 1738, December 1994.
Moats, R. URN Syntax, RFC 2141, May 1997.
Joint W3C/IETF URI Planning Interest Group. URIs, URLs, and
URNs: Clarifications and Recommendations 1.0. W3C Note.
2001. http://www.w3.org/TR/uri-clarification. Auch RFC 3305.
The Official IANA Registry of URI Schemes.
http://www.iana.org/assignments/uri-schemes
The Official IANA Registry of URN Namespaces.
http://www.iana.org/assignments/urn-namespaces
Robert Tolksdorf und Peter Löhr
34