Christoph Zurnieden: HTTP-Request abbrechen

Beitrag lesen

Hallo,

Viel zu aufwendig. Eine TCP-Verbindung lässt sich ohne weiteres mittendrin abbrechen und der Eigentümer (hier: der Webserver) der Verbindung wird darüber automatisch informiert.

Da würde ich jetzt aber gerne wissen, wie Du die Ausführung des TCP unterbrechen willst und zwar ohne Eingriffe in's OS oder den Stecker raus zu ziehen.

Indem man die Verbindung schließt, ganz einfach, zum Beispiel mit close() oder socket_close() oder was das System gerade dazu zur Verfügung stellt bzw. wie man die Verbindung aufgebaut hat (Dateisystem, Netzwerkebene).

Das ist "den Stecker rausziehen" ;-)

Aber es geht hier um die Clientseite. Da gibt es zuviele Clients als das man sich Serverseitig auf irgendetwas verlassen könnte.

Du musst nur dafür sorgen, daß Dein Skript auf dieses Ereignis reagiert.

Nun ist aber nach dem Absenden des Requests schon Ende.

Na, wo kriegt der Browser denn dann die Antwort her, wenn er nach dem Absenden der HTTP-Anfrage gleich die Verbindung kappt? Wie ungeduldig ;)

Doch, es ist dann Ende. Er kann nur die (fehlende) Response ignorieren und einen weiteren Request schicken.
Es ist auch nicht möglich ohne Nachfrage festzustellen, ob die Verbindung gekappt wurde, oder nur dauert. Da könnte dann nur ein brutales Timeout greifen. Siehe auch RFC 1122 u.N.

Genau so beim Response: Wenn ein Response vorliegt, ist das CGI meist schon fertig. Gäbe ja sonst auch kein Ergebnis, das raus zu schicken wäre.

Könntest Du Dich bitte auf Deutsch ausdrücken? Was meinst Du mit "wenn ein Response vorliegt"?

Falls Du Ausgaben meinst: Es hängt doch wohl vom Skript/Programm ab, wann es etwas ausgibt. Warum sollte es beispielsweise nicht als erstes den Seitenkopf ausgeben, dann seine Berechnungen durchführen, während dieser Berechnungen schon Teilergebnisse ausgeben und am Ende nochmal den Seitenfuß hinterherschicken. Dann wird während der gesamten Laufzeit des Skriptes etwas ausgegeben.

Ja, so funktioniert die Mehrzahl der Scripte.
Allerdings wird auch selten während der _ganzen_ Laufzeit der Scripte etwas ausgegeben.

Insofern verstehe ich nicht, warum "das CGI meist schon fertig" sein soll? Entsprechend obigem Ablauf würde ich glatt das genaue Gegenteil behaupten. Skripte geben eher nur in Ausnahmefällen einzig kurz vorm Beenden etwas aus. Da müsste man ja umständlicherweise sämtliche Ausgaben zwischendurch sammeln - diese Mühe werden sich meiner Einschätzung nach eher die wenigsten machen (sofern nicht schon eine Puffer-Automatik eingebaut ist).

Ja, es scheint, das ich hier zu sehr verallgemeinert habe.

Allerdings würde ich es nicht so bauen. Ich würde erst abwarten, ob das Script fehlerlos durchläuft, bevor ich anfange zu senden.
Insbesondere beim Forken von großen Datenbankabfragen ist das von Vorteil, da so ein Hauptteil der Fehler vorweg abgefangen werden können, da muß dann keiner warten, bis irgendwo ein Timeout greift.
Oder wie bei gzip, ob die Kompression jetzt funktioniert hat oder plain gesendet wird. Beides erfordert schließlich andere Header.

Nötigt natürlich zur sauberen Programmierung ;-)

Die einzige Ausnahme wäre ein Stream, das läuft aber bei Audio/Video nicht unbedingt über das HTT Protokol und da ist ein Abbruch auch direkt vorgesehen und fest eingebaut.

Äh, ich glaube, Du solltest Dich mal mit den Grundlagen von HTTP einerseits und TCP andererseits beschäftigen.

Noch näher?

Hey, ich habe tcp*.c schon nackich gesehen!
Pfui Deibel, nicht noch näher! ;-)

(Sorry, Allan, but you know what I mean, don't you? ;-)

HTTP hat mit der darunterliegenden Netzwerkverbindung TCP absolut garnichts zu tun. HTTP sieht keinen "Befehl" zum unerwarteten Beenden einer Verbindung vor, das stimmt. Das ist auch nicht nötig, weil man einfach die Netzwerkverbindung (TCP) beendet.

Und wie machst Du das sauber(!) mit einem Browser?

Ein HTTP-Client baut eine Verbindung zum HTTP-Server auf, diese Verbindung verwendet in der Regel das TCP-Protokoll - wie ein Großteil aller anderen Internetverbindungen auch.

Bemerkung des paranoiden Sicherheitsfanatikers: "Schlimm genug!"

Steht diese Verbindung, schicken sich die beiden Programme gegenseitig Daten, und zwar entsprechend dem HTTP-Protokoll.

Bemerkung eines bekannten Webserverprogammierers:"Schön wär's!"

Diese TCP-Verbindung steht (sofern sie nicht abgebrochen wird) während des gesamten Austauschs von Anfrage und Antwort und, bei keep-alive-HTTP-Verbindungen, auch noch für weitere Anfrage/Antwort-Pärchen, ähnlich einem Telefongespräch.

Bitte mit einem mehr oder minder kurzem Zitat aus RFC 2616 belegen, danke.
(Tip: steht ganz oben)
Und jetzt auch noch aus RFC 1122
Aha, dacht' ich mir ;-)

Ich hoffe Du kannst jetzt nachvollziehen, warum sich manch' Programmierer, der sowas implementieren soll, ernsthaft fragt, welcher hirnverbrannte Idiot sich Derartiges ausdenkt.

"Ein gewachsenes System", nun:"Gewuchert" träfe es eher.

TCP kannst Du Dir als das Telefonnetz vorstellen, daß Deine Töne (Worte) transportiert, HTTP definiert die Sprache, also die Worte, die Du benutzt: Deutsch, Englisch, Suaheli.

Schöner Vergleich. Hinkt zwar arg, aber tät er das nicht, wär's kein Vergleich, oder? ;-)

Nein, ernsthaft, gutes Bild, sollte man sich merken.

Du stellst also erst die Verbindung her, indem Du den Telefonhörer abhebst und wählst, und wenn die Verbindung steht (bis hier hin TCP), kommunizierst Du mit der "Gegenstelle" (HTTP). Die "HTTP-Verbindung" kannst Du zu jeder beliebigen Zeit abbrechen, indem Du den Telefonhörer auflegst.

Aha, hier hakt das Bild. Nach HTTP würdest Du einfach mit dem Sprechen aufhören. Ob Du auflegst interessiert HTTP nicht mehr. Das muß der Browser (Im HTTP heißt er ganz allgemein "User Agent", kann ja auch LWP::Simple sein, o.ä.) bzw der Server dann erledigen.

Und Deine Gegenstelle bekommt das dann entsprechend signalisiert - ist sie klug, reagiert sie darauf, wenn nicht, sabbelt sie solange weiter, bis sie merkt, daß keine Antwort mehr kommt (Neudeutsch: Timeout).

Wie man eine TCP-Verbindung in der Praxis aufbaut und dann für HTTP verwendet, kannst Du Dir unter http://www.php.net/manual/de/ref.sockets.php, Beispiel 2, anschauen. Das ist zwar PHP (hab auf die schnelle nichts schöneres gefunden), tut aber nichts zur Sache, denn das Prinzip ist immer dasselbe (weil alle auf demselben Software-Urahn aufbauen).

Kann PHP nicht gut genug, bin da eher C-Programmierer und würde dafür in den Kernel schauen.
Aber nur unter Zwang! ;-)

Unter Umständen etwas hinderlich könnten allerdings Caches sein, die dafür sorgen, daß die Anfrage komplett ausgeführt wird, egal ob der Browser die Verbindung beendet hat oder nicht.

Was hat das mit Caches zu tun?

Wenn der Anzeigeteil eines Browsers ein Dokument abfragt, aber vorzeitig abricht, bedeutet das noch lange nicht, daß ein zwischen Anzeigeteil und Server sitzender Cache, egal welcher Art, die Verbindung zum Server ebenfalls abbricht.
Der Cache könnte sich ja genauso gut denken "Na, die Anfrage wurde zwar abgebrochen, aber wenn sie nochmal kommt, hab ich die Antwort schon hier" und lässt den Server trotzdem weiterarbeiten.

Naja, wenn's dann zu Proxies etc kommt, wird's ganz kniffelig und gefährdet arg die geistige Gesundheit. Sollte man bei solchen Überlegungen sicherheitshalber außen vor lassen. Ist gesünder.

so short

Christoph Zurnieden