Dako_Anwendungen_Web¶
ehemalige Veranstaltungen ia3.netz + ia3.data sowie ia4.Netz im Studiengang Interaktive Medien
(c) 2020/2021 Hochschule Augsburg - Fakultät für Informatik - Prof.Dr.Nik Klever
Anwendungen der Datenkommunikations-Anwendungsschicht - Web¶
Telnet - Web - E-Mail¶
Die meisten Anwendungen aus dem Internet wurden bereits in den 80er und frühen 90er Jahren entwickelt. Die frühen Anwendungen waren dabei, sich in einen entfernten Rechner per Telnet einzuloggen, eine Nachricht per SMTP zu verschicken oder eine Datei per FTP auf einen entfernten Rechner zu übertragen.
Erst in den frühen 90er Jahren kam der Siegeszug des Web mit dem HTTP Protokoll hinzu. Alle diese Protokollen bauen auf dem Prinzip auf, dass eine entsprechende Verbindung der Transportschicht zu einem entfernten Rechner aufgebaut wird und auf dieser Verbindung ein auf dem ASCII-Zeichensatz bestehendes und damit lesbares Protokoll verwendet wird.
RFC (Request for Comment)¶
- Definitionen und Standards für alle Protokolle des Internets
- Verantwortliche Organisation IETF - Internet Engineering Task Force - Standards
- Die meisten Definitionen, wie ein Standard aufgebaut ist, sind in der sog. erweiterten Backus-Naur Form (BNF), einer Meta-Sprache beschrieben, wie sie ursprünglich in dem RFC 822 definiert wurde. Eine gute Beschreibung findet sich jedoch auch im Kapitel 2.1 Augmented BNF des unten beschriebenen [HTTP – Hypertext Transfer Protocol] (RFC 2616)](http://tools.ietf.org/html/rfc2616) Standards.
Telnet Protocol¶
Das Telnet Protokoll hat den großen Vorteil, dass es eine Verbindung auf der Transportschicht aufbaut und je nachdem, welche Adresse (Port) verwendet wird, das entsprechende Protokoll manuell emuliert werden kann, sodass man aus diesem manuellen Nachvollziehen sowohl das Prinzip des Protokolls verstehen als auch Fehler in der Implementierung eines Servers damit testen kann.
Austausch von Zeichen¶
Austausch von Zeichen nach dem ASCII-Zeichensatz zwischen Client und Server -> damit die Basis für alle textbasierten Anwendungsprotokolle
Definition eines virtuellen Terminals als verbindlichem Standard, was Zeichen und Zeichensätze angeht
- VAX-Rechner, IBM-Mainframes, Sun-Workstations, Amigas, Ataris, PCs, Macs, ...
- einheitlicher Standard NVT (Network Virtual Terminal)
Aushandeln und Einstellen von Verbindungsoptionen
- Blockmode vs. Single-Character-Mode
Beispiele von Steuercodes mit besonderer Bedeutung¶
| Character | Code |
|---|---|
| CR (Carriage Return) | 0x13 |
| LF (Line Feed) | 0x10 |
| BS (Back Space) | 0x08 |
| EC (Erase Character) | 0x247 |
| EL (Erase Line) | 0x248 |
Zeichensätze¶
Eine allgemeine Übersicht über bestehende Zeichensätze im Internet findet man auf der Character Sets Webseite der IANA, der Internet Assigned Numbers Authority, die für die Registrierung diverser Nummern, Protokolle und Daten im Internet zuständig ist.
Eine gute Übersicht über den ASCII Zeichensatz liefert auch Wikipedia, bzw. die entsprechende deutsche Wikipedia Seite.
Chance im Team¶
Bauen sie in einer Shell eine Telnet Verbindung zu towel.blinkenlights.nl auf und beschreiben, was passiert. In Windows muss dafür das Programm Telnet erst über die Systemsteuerung freigeschaltet werden.
Telnet-Beispiel mit Python¶
Anstatt einen Telnet-Aufruf manuell in einer Shell (cmd,shell,etc.) einzugeben, kann man diesen Aufruf auch in einem sehr einfachen kleinen Python-Programm mittels der Telnet-Bibliothek telnetlib vorbereiten, um die Befehle damit aufzurufen. Dies hat den Vorteil, dass die entsprechenden Befehle nicht langwierig im Telnet-Programm manuell eingegeben werden müssen, was manchmal auch zu einem Verbindungsabbruch führt (z.B. bei einem server-seitigen Timeout von wenigen Sekunden)
from telnetlib import Telnet
connection = Telnet('towel.blinkenlights.nl')
response = connection.read_until(b"We're doomed!",timeout=120)
reduced = response[:1000]+b"\n\n\n\n ... \n\n\n\n"+response[-1000:]
print(reduced)
b"\x1b[H\x1b[J\x1b[H\r\n\r\n\r\n\r\n\r\n\r\n \r\n Original Work : Simon Jansen ( http://www.asciimation.co.nz/ ) \r\n Telnetification : Sten Spans ( http://blinkenlights.nl/ ) \r\n Terminal Tricks : Mike Edwards (pf-asciimation@mirkwood.net) \r\n \r\n The hard work was done by Simon and Mike, \r\n I just placed it online in a different format. \r\n \r\n So long And Thanks for all the fish \r\n \r\n Sten (I just need a Hug) \r\n \r\n \x1b[H\r\n\r\n\n\n\n ... \n\n\n\n \r\n _\\=/_ \r\n ___ # / _ \\ # \r\n / ()\\ \\\\//|/.\\|\\\\// \r\n _|_____|_ \\/ \\_/ \\/ \r\n | | === | | |\\ /| \r\n |_| O |_| \\_ _/ \r\n || O || | | | \r\n ||__*__|| | | | \r\n |~ \\___/ ~| []|[] \r\n /=\\ /=\\ /=\\ | | | \r\n ________________[_]_[_]_[_]________/_]_[_\\_________________________\x1b[H\r\n\r\n\r\n\r\n\r\n\r\n /~\\ \r\n |oo ) We're doomed!"
print(reduced.decode('utf-8'))
Original Work : Simon Jansen ( http://www.asciimation.co.nz/ )
Telnetification : Sten Spans ( http://blinkenlights.nl/ )
Terminal Tricks : Mike Edwards (pf-asciimation@mirkwood.net)
The hard work was done by Simon and Mike,
I just placed it online in a different format.
So long And Thanks for all the fish
Sten (I just need a Hug)
...
_\=/_
___ # / _ \ #
/ ()\ \\//|/.\|\\//
_|_____|_ \/ \_/ \/
| | === | | |\ /|
|_| O |_| \_ _/
|| O || | | |
||__*__|| | | |
|~ \___/ ~| []|[]
/=\ /=\ /=\ | | |
________________[_]_[_]_[_]________/_]_[_\_________________________
/~\
|oo ) We're doomed!
Telnet.read_until(expected[, timeout]) -- Read until a given string, expected, is encountered or until timeout seconds have passed. When no match is found, return whatever is available instead, possibly the empty string. Raise EOFError if the connection is closed and no cooked data is available.
Telnet.read_all() -- Read all data until EOF; block until connection closed.
Telnet.read_some() -- Read at least one byte of cooked data unless EOF is hit. Return '' if EOF is hit. Block if no data is immediately available.
Telnet.read_very_eager() -- Read everything that can be without blocking in I/O (eager). -- Raise EOFError if connection closed and no cooked data available. Return '' if no cooked data available otherwise. Do not block unless in the midst of an IAC sequence.
Telnet.read_eager() -- Read readily available data. -- Raise EOFError if connection closed and no cooked data available. Return '' if no cooked data available otherwise. Do not block unless in the midst of an IAC sequence.
Telnet.read_lazy() -- Process and return data already in the queues (lazy). -- Raise EOFError if connection closed and no data available. Return '' if no cooked data available otherwise. Do not block unless in the midst of an IAC sequence.
Telnet.read_very_lazy() -- Return any data available in the cooked queue (very lazy). -- Raise EOFError if connection closed and no data available. Return '' if no cooked data available otherwise. This method never blocks.
Telnet.read_sb_data() -- Return the data collected between a SB/SE pair (suboption begin/end). The callback should access these data when it was invoked with a SE command. This method never blocks.
Bitte unbedingt beachten:¶
Diese unterschiedlichen Methoden sind bei der Verwendung in einer Jupyter Notebook-Zelle von Bedeutung, da zum einen der entsprechende Kernel-Prozess des Jupyter Notebooks blockieren kann und zum anderen aber die Abarbeitung der Telnet-Verbindung in der Regel länger dauert als der I/O-Vorgang des Kernels zum (in der Regel lokalen) Browser-Fenster.
Empfohlen wird der Aufruf der Funktion read_very_eager, allerdings sollten sie den Aufruf dieser Funktion jeweils nur einzeln alleine in einer Zelle ausführen. Es kann jedoch vorkommen, dass nicht sofort eine Ausgabe zurückkommt, dann sollten sie diesen Aufruf entsprechend wiederholen.
Der Aufruf der Funktion read_all kann aufgrund nicht sofort schliessender Telnet-Verbindungen zu einem länger oder auch permanenten Blockieren führen und könnte dann nur durch einen Kernel-Interrupt (bzw. Restart) abgebrochen werden.
HTTP – Hypertext Transfer Protocol¶
Das Protokoll ist im Wesentlichen auf einem Anfrage (Request) - Antwort (Response) Verhalten aufgebaut.
Im Unterschied zu allen anderen Protokollen bleibt jedoch die Verbindung zwischen Server und Client nicht erhalten, HTTP ist ein sog. zustandsloses Protokoll (stateless protocol), weswegen HTTP auch die Session-Problematik kennt (also die Frage, wie ein Zustand (z.B. die Einträge in einem Warenkorb) über mehrere Anfragen erhalten bleibt).
allgemeines Verhalten in einer Client-/Server-Verbindung¶
HTTP-Anfrage (HTTP-Request)
| Method | SP | Request-URI | SP | HTTP-Version | CRLF | Request-Line |
|---|---|---|---|---|---|---|
| Field-Name | : | Field-Value | CRLF | |||
| ... | Message-Header-Lines | |||||
| Field-Name | : | Field-Value | CRLF | |||
| CRLF | Separator-Line | |||||
| Body | ||||||
Allgemeine Definition eines Requests¶
Die allgemeine Definition eines Requests ist in Kapitel 5 des Standards in der erweiterten Backus-Naur-Form folgendermaßen beschrieben:
Request = Request-Line
*( general-header | request-header | entity-header )
CRLF
[ message-body ]
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
Method = "OPTIONS"
| "GET"
| "HEAD"
| "POST"
| "PUT"
| "DELETE"
| "TRACE"
| extension-method
general-header = Cache-Control
| Connection
| Date
| Pragma
| Trailer
| Transfer-Encoding
| Upgrade
| Via
| Warning
Connection = "Connection" ":" 1#(connection-token)
connection-token = token
HTTP/1.1 defines the "close" connection option for the sender to
signal that the connection will be closed after completion of the
response. For example,
Connection: close
in either the request or the response header fields indicates that
the connection SHOULD NOT be considered `persistent' (section 8.1)
after the current request/response is complete.
request-header = Accept
| Accept-Charset
| Accept-Encoding
| Accept-Language
| Authorization
| From
| Host
| If-Modified-Since
| If-Match
| If-None-Match
| If-Range
| If-Unmodified-Since
| Max-Forwards
| Proxy-Authorization
| Range
| Referer
| User-Agent
Request-URI = "*" | absoluteURI | abs_path
Beispielhafte Auswahl der wichtigsten Methoden und Header-Felder eines Requests¶
Methoden (Client-Befehle)
- GET / HTTP/1.0
- HEAD http://www.dfn.de HTTP/1.1
- POST /www/project/index.html HTTP/0.9
Header-Felder (Client-Attribute)
- Host: www.audi.de
- Authorization: Basic Base64-coded-Username:Password-String
Chance im Team¶
Verwenden sie die Telnet-Bibliothek telnetlib um das eben gesehene Beispiel zu reproduzieren.
Bauen sie eine Verbindung zu www.w3.org mit dem Port 80 auf und schicken einen Request auf die Seite /pub/WWW/TheProject.html entsprechend dem Beispiel im Kapitel 5.1.2. aus dem HTTP-Standard RFC 2616
from telnetlib import Telnet
connection = Telnet('www.w3.org',80)
connection.write(b'GET /pub/WWW/TheProject.html HTTP/1.1\r\n')
connection.write(b'Host: www.w3.org\r\n')
connection.write(b'\r\n')
response = connection.read_all()
print(response[:1000])
b'HTTP/1.1 301 Moved Permanently\r\nDate: Mon, 05 Nov 2018 20:34:03 GMT\r\nLocation: http://www.w3.org/TheProject.html\r\nCache-Control: max-age=21600\r\nExpires: Tue, 06 Nov 2018 02:34:03 GMT\r\nContent-Length: 241\r\nContent-Type: text/html; charset=iso-8859-1\r\nVary: upgrade-insecure-requests\r\n\r\n<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>301 Moved Permanently</title>\n</head><body>\n<h1>Moved Permanently</h1>\n<p>The document has moved <a href="http://www.w3.org/TheProject.html">here</a>.</p>\n</body></html>\n'
print(response[:1000].decode("utf-8"))
HTTP/1.1 301 Moved Permanently Date: Mon, 05 Nov 2018 20:34:03 GMT Location: http://www.w3.org/TheProject.html Cache-Control: max-age=21600 Expires: Tue, 06 Nov 2018 02:34:03 GMT Content-Length: 241 Content-Type: text/html; charset=iso-8859-1 Vary: upgrade-insecure-requests <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="http://www.w3.org/TheProject.html">here</a>.</p> </body></html>
HTTP-Antwort (HTTP-Response)
| HTTP-Version | S | Status-Code | S | Reason-Phrase | CRLF | Status-Line |
|---|---|---|---|---|---|---|
| Field-Name | : | Field-Value | CRLF | |||
| ... | Message-Header-Lines | |||||
| Field-Name | : | Field-Value | CRLF | |||
| CRLF | Separator-Line | |||||
| Body | ||||||
Allgemeine Definition eines Response¶
Die allgemeine Definition der Antwort auf einen Request, also einem Response ist in Kapitel 6 des Standards in der erweiterten Backus-Naur-Form folgendermaßen beschrieben:
Response = Status-Line
*( general-header | response-header | entity-header )
CRLF
[ message-body ]
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
Status-Codes 1xx, 2xx, 3xx¶
Status-Code = "100" ; Continue
| "101" ; Switching Protocols
| "200" ; OK
| "201" ; Created
| "202" ; Accepted
| "203" ; Non-Authoritative Information
| "204" ; No Content
| "205" ; Reset Content
| "206" ; Partial Content
| "300" ; Multiple Choices
| "301" ; Moved Permanently
| "302" ; Moved Temporarily
| "303" ; See Other
| "304" ; Not Modified
| "305" ; Use Proxy
Status-Codes 4xx¶
| "400" ; Bad Request
| "401" ; Unauthorized
| "402" ; Payment Required
| "403" ; Forbidden
| "404" ; Not Found
| "405" ; Method Not Allowed
| "406" ; Not Acceptable
| "407" ; Proxy Authentication Required
| "408" ; Request Time-out
| "409" ; Conflict
| "410" ; Gone
| "411" ; Length Required
| "412" ; Precondition Failed
| "413" ; Request Entity Too Large
| "414" ; Request-URI Too Large
| "415" ; Unsupported Media Type
Status-Codes 5xx¶
| "500" ; Internal Server Error
| "501" ; Not Implemented
| "502" ; Bad Gateway
| "503" ; Service Unavailable
| "504" ; Gateway Time-out
| "505" ; HTTP Version not supported
| extension-code
Reason-Phrase und Response-Header¶
Reason-Phrase = *<TEXT, excluding CR, LF>
response-header = Age
| Location
| Proxy-Authenticate
| Public
| Retry-After
| Server
| Vary
| Warning
| WWW-Authenticate
HTML - Hypertext Markup Language¶
Das Format, in dem Webseiten geschrieben werden, ist HTML und ist in der Version 2.0 zwar auch als RFC Standard Hypertext Markup Language - 2.0 (RFC 1866) definiert, aber die eigentliche Standardisierung findet am W3C, dem WWW-Consortium statt. Das W3C ist ein offenes Consortium von Firmen, Organisationen und Behörden mit Sitz in Genf. Alle Standards, die zum Web gehören werden dort diskutiert und verabschiedet, siehe W3C Standards.