Eigenen HTTP-Server Programmieren

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Hannibal42
User
Beiträge: 5
Registriert: Sonntag 6. Februar 2011, 22:51

Hallo ich habe vor einen kleine HTTP Server zu programmieren mit dem man nachher über eine Website Daten hoch und runter laden kann. Ich hab auch schon gesehen das Python einen eigenen Server als Modul hat, doch würde ich gerne etwas eigenes schreiben. Meine Frage ist jetzt wie aufwendig so etwas ist. Bin gerade dabei mich über Sockets schlau zu machen, mir fehlt aber leider immer noch der Überblick wie komplex das ganze wird.

Ist so etwas gut zu realisieren oder sollte ich besser auf den bestehenden Server zurück greifen ?

Schon mal Danke für die Antworten

Hannibal
BlackJack

@Hannibal42: Wie aufwendig das ist kannst Du Dir doch ganz einfach an dem Quelltext für den Webserver in der Standardbibliothek anschauen.

Du müsstest halt Socket-Programmierung betreiben und die entsprechenden RFCs für HTTP umsetzen.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

HTTP/0.9 und HTTP/1.0 sind relativ einfach umzusetzen. HTTP/1.1 (der aktuelle Standard) vergleichsweise aufwendig. Glücklicherweise darf der Server bestimmen, welcher HTTP-Dialekt gesprochen wird. Der Client schickt einen Request, der Server antwortet mit einer Response. Das ist normale Socket-Kommunikation. Das Protokoll ist lesbar, Octets (im Header) sind nach ISO-8859-1 kodiert.

In HTTP/0.9 schickt der Client einfach den String "GET /<path>" und schließt die Zeile netzwerkprotokolltypisch mit \r\n (Bytes 13 + 10) ab. Der Pfad darf keine Leerzeichen enthalten und muss mit einem / beginnen. Die HTTP-Methode muss groß geschrieben sein und ist durch ein Leerzeichen vom Pfad getrennt. Ab HTTP/1.0 gibt es einen dritten Parameter in der Zeile, ebenfalls durch ein Leerzeichen abgetrennt: die HTTP-Version, so geschrieben wie hier zu sehen. Folgt die HTTP-Version, endet der Request erst durch \r\n\r\n (eine Leerzeile) und alle weiteren Zeilen werden als Schlüssel-Wert-Paare aufgefasst. Der Schlüssel kann eine beliebige Folge von Zeichen außer Leerzeichen und ":" sein, letzteres trennt Schlüssel von Wert. Der Wert ist alles bis zum durch \r\n definierten Zeilenende. Pflichtangabe für Clients ist der Host, z.B. "Host: www.python-forum.de". Groß- und Kleinschreibung ist bei den Schlüsseln egal und ich hoffe, es gibt eine Regelung, wie Ä oder andere Buchstaben außerhalb von A-Z umgewandelt werden. Es gibt noch ein paar Ausnahmen, wie Schlüssel und Werte mit Hilfe von Escape-Zeichen über mehr als eine physikalische Zeile aufgeteilt werden und wie Leerzeichen "getrimmt" werden müssen. Ein Wert kann auch noch ein anderes Encoding haben, aber vielleicht ist das auch schon HTTP/1.1. Ich glaube, HTTP/1.0 regelt auch nicht eindeutig, wie mit Sonderzeichen in Pfaden umgegangen wird. UTF-8 ist hier eine übliche Kodierung.

Bei HTTP/0.9 antwortet der Server einfach mit dem Inhalt der angeforderten Ressource und beendet dann die Netzwerkverbindung. Ab HTTP/1.0 gibt es einen Header, der genauso aufgebaut ist, wie beim Request, eine Leerzeile trennt Kopf vom Rumpf und bis dahin ist alles ISO-8859-1 kodiert, danach so, wie im Header angegeben. Der Header beginnt mit einer Zeile die als erstes die Protokollversion, dann getrennt durch ein Leerzeichen der HTTP-Statuscode, z.B. 200, dann getrennt durch ein Leerzeichen bis zum Zeilenende eine textuelle Beschreibung des Status enthält. Z.B. "HTTP/1.0 404 Not found". Danach kommen wieder Schlüssel und Werte wobei ein "Content-Type" dringend angeraten ist, ein "Content-Length" empfohlen wird und irgendwas, dich glaube "Date" zwingend erforderlich ist. Ab HTTP/1.0 kann der Server auch darauf verzichten, das Socket zu schließen und/oder ein anderes, sogenanntes chunked encoding, benutzen, was beides effizienter ist.

Wenn's aber nur ums Prinzip geht, dann kann man mit http://www.w3.org/Protocols/HTTP/AsImplemented.html anfangen und dann schauen, was HTTP/1.0 ergänzt hat. Das komplette HTTP/1.1-Protokoll würde ich freiwillig nicht implementieren wollen. Das haben schon andere gemacht ;)

Stefan
Hannibal42
User
Beiträge: 5
Registriert: Sonntag 6. Februar 2011, 22:51

Danke für die schnelle Antwort, werde mir alles genau ansehen und dann entscheiden ob ich das so machen kann wie ich es mir vorstelle.

Kennt ihr vieleicht ein gutes Buch zu diesem Thema, was etwas genauer auf die Zusammenhänge eingeht ? Im Web habe ich bis jetzt nur bruchstückhafte Informationen gefunden.

Grüße Simon
Benutzeravatar
daemonTutorials
User
Beiträge: 171
Registriert: Sonntag 6. Februar 2011, 12:06
Kontaktdaten:

Meistens nicht anderes als das Gute Python3 Mini Buch von Galileo Computing(<openbook>) oder das Große Pthon3 von Galileo Computing.
LG Maik
BlackJack

@Hannibal42: Zur Socket-Programmierung kann man auch Literatur nehmen, die sich an C-Programmierer wendet, denn das `socket`-Modul ist nur eine recht dünne Schicht über der C-Bibliothek.

Und für HTTP hat sma ja schon den Link zur Beschreibung von Version 0.9 eingeworfen. Die beiden Version 1.0 und 1.1 werden in den entsprechenden RFCs ziemlich detailliert definiert:

rfc1945: Hypertext Transfer Protocol -- HTTP/1.0
rfc2616: Hypertext Transfer Protocol -- HTTP/1.1

@daemonTutorials: Die Python-Bücher von Galileo-Computing sind nicht gut. Da wird kein idiomatisches Python verwendet.
Benutzeravatar
daemonTutorials
User
Beiträge: 171
Registriert: Sonntag 6. Februar 2011, 12:06
Kontaktdaten:

@BlackJack: Welche Bücher empfiehlst du mir denn?
LG Maik
BlackJack

@daemonTutorials: Kommt auf den Kenntnisstand an. Für den Einstieg das Tutorial aus der Python-Dokumentation und `A Byte Of Python` ist ganz gut. Ersteres gibt es für Python 3 auch auf deutsch und letzteres für Python 2.x.
Benutzeravatar
daemonTutorials
User
Beiträge: 171
Registriert: Sonntag 6. Februar 2011, 12:06
Kontaktdaten:

Vielen Dank BlackJack, von 'A Byte of Python' habe ich auch schon gehört! Leider habe ich es nie so richtig kapiert!
LG Maik
Hannibal42
User
Beiträge: 5
Registriert: Sonntag 6. Februar 2011, 22:51

@daemonTutorials: Zum nachschlagen kann man auch gut Python GE-PACKT benutzen.
Antworten