PHP: HTTP-Requests

M

mdo

Guest
Hallo,

ich möchte mit PHP HTTP-Requests an Server stellen. Das PHP-Skript, welches durch einen Browser aufgerufen wird, soll also einen weiteren Server per HTTP kontaktieren und dort Daten runterladen.

Dabei gibt es ein paar Voraussetzungen:
- Header senden
- Zugriff auf die Header, die vom fremden Server gesendet werden
- Zugriff auf die herunterzuladenden Daten schon während der Übertragung

Wenn es auch nicht das trifft, was ich umsetzen will: am einfachsten Stellt man sich einen HTTP-Proxy vor. Ich möchte also schon während des Herunterladens die Daten an den anfragenden Client weiterreichen.

fopen() ist einfach zu handhaben und ermöglicht den letzten Punkt dadurch, dass ein Handle vorhanden ist. Jegliche erweiterte Funktionalität ist damit aber mWn nicht umzusetzen. CURL, einige PEAR-Pakete und dergleichen sind wohl nur in der Lage, nach der Abfrage die kompletten Daten auf einen Schlag zu liefern.

Sicherlich gibt es irgendeine bestehende Lösung, für jeglichen Tipp bin ich dankbar.

mdo

 
QUOTE (mdo @ Fr 19.1.2007, 20:43) Wenn es auch nicht das trifft, was ich umsetzen will: am einfachsten Stellt man sich einen HTTP-Proxy vor. Ich möchte also schon während des Herunterladens die Daten an den anfragenden Client weiterreichen.

Das hört sich nach einer ziemlich verknoten Dreiecksgeschichte an.
Man kann dem Klienten nur eine Datei liefern.

Was der andere Kram nun besser kann als PHP kann ich nicht beurteilen. Aber ist das Problem nicht eventuell das man dem Klienten nur das liefern kann, was er anfordert? Eventuell müssen einfach die Sachen vom eigenen Server und die vom externen Server in einer ZIP-Datei zusammengepackt werden?
 
QUOTE Man kann dem Klienten nur eine Datei liefern.


Mehr habe ich auch nicht vor. Wie gesagt: man stelle sich einfach einen HTTP-Proxy (wie Squid) vor, der in PHP implementiert wird.

Die gewünschte Funktionalität lässt sich vom Grundsatz her in ein paar Zeilen coden: fopen("http://meine.url/","r") und dann in einer while-Schleife fgets() und ein print für die Ausgabe zum Client. Für eine Anfrage per HTTP kann ich dem Client natürlich auch nur eine Antwort/Datei/Resource schicken. Zwischen dem fgets() und dem print kann ich dann halt alle Aktionen ausführen, die ich möchte. Bei CURL kann ich das mWn nicht, da müsste ich erst den kompletten Download abwarten.

 
Mit fopen wird das nix. Dazu musst du mit Sockets arbeiten. Unter PHP geht das recht gut mit fsockopen. In den Kommentaren unten hats genügend Beispiele..
 
QUOTE (Alonso @ Fr 19.1.2007, 23:47)Mit fopen wird das nix. Dazu musst du mit Sockets arbeiten. Unter PHP geht das recht gut mit fsockopen. In den Kommentaren unten hats genügend Beispiele..

Nur müsste ich dann das gesamte HTTP-Protokoll abbilden. Oder eine existierende Klasse, ein Pear-Modul, whatever umbauen. Ich hege eigentlich immer noch die Hoffnung, dass irgendwer eine "fertige" Lösung kennt.

 
QUOTE (mdo @ Fr 19.1.2007, 23:34)
QUOTE (Alonso @ Fr 19.1.2007, 23:47)Mit fopen wird das nix. Dazu musst du mit Sockets arbeiten. Unter PHP geht das recht gut mit fsockopen. In den Kommentaren unten hats genügend Beispiele..

Nur müsste ich dann das gesamte HTTP-Protokoll abbilden. Oder eine existierende Klasse, ein Pear-Modul, whatever umbauen. Ich hege eigentlich immer noch die Hoffnung, dass irgendwer eine "fertige" Lösung kennt.

Dann beschreib doch einfach mal, was du machen willst.
Du machst in deiner Beschreibung oben einen blumigen Eiertanz mit, allerlei Fachwörtern gespickt, um die Problembeschreibung herum.

Für die Lösung des Problems musst du nicht das Internet neu erfinden.


QUOTE CURL, einige PEAR-Pakete und dergleichen sind wohl nur in der Lage, nach der Abfrage die kompletten Daten auf einen Schlag zu liefern.


Wie soll da eigentlich die Interaktion mit dem Nutzer funktionieren?
Der Nutzer macht 1 Anfrage und bekomt X-Dateien gedrückt. Wie soll das mit einem handelsüblichen Browser gehen?
 
Ich weiß zwar nicht, wo der blumige Eiertanz stattfand, aber als Einsatzzweck kann man sich einfach -- wie zuvor erwähnt -- einen HTTP-Proxy vorstellen. Meinetwegen will ich Squid in PHP nachprogrammieren. Es geht mir aber nicht um das ganze Drumherum, sondern lediglich um a) das Herunterladen und b) das gleichzeitige Weitersenden der Daten an den Client.

Wenn der Client nun eine 200 MB große Datei anfragt, soll der nicht solange warten, bis der Proxy (PHP-Skript) die vom "Upstream-Server" komplett heruntergeladen hat, sondern schon Daten gesandt bekommen, sobald das PHP-Skript welche erhält.

Jeder handelsübliche Browser kann das übrigens, indem man einen Proxy-Server darin einstellt.

 
QUOTE (mdo @ Sa 20.1.2007, 1:35) Jeder handelsübliche Browser kann das übrigens, indem man einen Proxy-Server darin einstellt.

Ja, wenn du ihm einen Proxy angibst. Aber wie willst du dem Browser beibringen, eine normale Webseite als Proxy zu akzeptieren? Ich sehe den Sinn deines Vorhabens ehrlich gesagt auch nicht. Wenn ich dich richtig verstehe, willst du sowas in der Art eines Anonymizer-Service aufbauen?

Eine 200MB Datei in purem HTML abzubilden dürfte relativ schwer sein
wink.gif
Abgesehen davon wirst du dir die Zähne ausbeissen, solch grosse Datenvolumen im grossen Stil mit PHP zu verarbeiten..
 
Irgendwie kommt mir der ganze Thread etwas merkwürdig vor:

@mdo: Einerseits willst Du irgendetwas 'wichtiges' machen, andererseits verstehst Du noch nicht einmal diese Beispiele unter fsockopen, die sogar ich als PHP-Nicht-Verwender hinreichend rasch nachvollziehen kann.

Die einzigste ernsthafte Verwendung besteht für mich darin, daß Du - eher illegal - irgendwelche großen Streams (ab einer Minute Dauer) abrufen und diese Clients natürlich nicht erst nach dem kompletten Download zusenden willst. Weder für Html-Seiten, Bilder oder bsp. Word-Dokumente macht dein Wunsch Sinn, die funktionieren immer nur als Ganzes. Bei Streams ist so ein Verfahren technisch möglich, weil man die clientseitig schon verarbeiten kann, während der Download noch läuft.
 
Ich hab sowas mal gemacht, allerdings nicht in PHP. Sinn und Zweck davon war quasi ein Werbefilter-Proxy. Dem Browser kann man das Teil dann als Proxy einstellen, aber es wäre natürlich auch möglich, es als TCP/IP-Gateway einzustellen - wenn der Clientbrowser grundsätzlich nur bestimmte Protokolle nutzen darf.

In Dotnet ist das relativ einfach: ein TCP-Listener, der auf Client-Anfragen hört, und dazu ein Clientsocket für die Kommunikation mit den (externen) Webservern. Jeder Request vom Clientbrowser wird dann einfach an den entsprechenden Webserver geschickt, und dessen Antwort wiederum an den Clientbrowser zurückgesandt. Da das Networking in Dotnet mit Streams arbeitet, kann ich problemlos jedes Byte-Paket, das vom Webserver geliefert wird, direkt an den Client schicken und muss nicht warten bis die Antwort komplett da ist.
In meinem Fall hab ich für den TCP-Listener einen HTTPHandler benutzt; der lässt sich in den IIS integrieren und so musste ich das HTTP-Protokoll nicht selber implementieren. Für den Clientsocket hab ich den vorhandenen Webrequest benutzt, da ich nur HTTP benötige und keine anderen Protokolle.

Ob und wie das in PHP geht, weiss ich nicht, da ich kein PHP kann ;-)

Griessli
Irene
 
QUOTE (Irene @ Sa 20.1.2007, 10:54)Ich hab sowas mal gemacht, allerdings nicht in PHP. Sinn und Zweck davon war quasi ein Werbefilter-Proxy.


Na also. Danke Irene für den konstruktiven Beitrag. Eben genau die Umsetzung in PHP ist mein Problem.


QUOTE (jAuer @ Sa 20.1.2007, 9:36)@mdo: Einerseits willst Du irgendetwas 'wichtiges' machen, andererseits verstehst Du noch nicht einmal diese Beispiele unter fsockopen, die sogar ich als PHP-Nicht-Verwender hinreichend rasch nachvollziehen kann.


So so, große Worte. Jeder der sich mal die entsprechenden RFCs anschaut, wird sehen, dass es nicht damit getan ist, mittels fsockopen() einen Socket aufzubauen, den GET-Request zu senden und dann auf die Daten zu warten. Das HTTP-Protokoll sieht da noch ein paar Möglichkeiten mehr vor. Es geht schlicht und ergreifend darum, dass ich kein Interesse daran habe, "das Rad neu zu implementieren", will sagen: ich möchte mir den Aufwand sparen, etwas komplett selbst zu programmieren, falls es sowas wie eine libwget (Achtung: nicht existierendes Beispiel) oder was auch immer für PHP geben sollte.


QUOTE (jAuer @ Sa 20.1.2007, 9:36)Die einzigste ernsthafte Verwendung besteht für mich darin, daß Du - eher illegal - irgendwelche großen Streams (ab einer Minute Dauer) abrufen und diese Clients natürlich nicht erst nach dem kompletten Download zusenden willst.

*prust* Also ich persönlich möchte den Client auch schon bei legalen halbgroßen Downloads, deren Daten eine halbe Minute Dauer umfassen, nicht unnötig warten lassen.


QUOTE (jAuer @ Sa 20.1.2007, 9:36)Weder für Html-Seiten, Bilder oder bsp. Word-Dokumente macht dein Wunsch Sinn, die funktionieren immer nur als Ganzes. Bei Streams ist so ein Verfahren technisch möglich, weil man die clientseitig schon verarbeiten kann, während der Download noch läuft.

Es ist beinahe bei jeglichem Dokument sinnvoll es als Proxy auf diese Art und Weise zu verarbeiten. Jegliche Verzögerung bis zum Senden der ersten Daten bedeutet dem Client-Browser eine Wartezeit, während derer nichts geschieht. Wird bspw. ein großes JPG vom Upstream-Server geholt, der die Daten seinerseits schon nur langsam sendet, könnte das Bild mit und mit bereits im Client-Browser angezeigt werden.

Es ging nur um die technische Umsetzung, nicht um eine Grundsatzdiskussion über die Legalität einer möglichen Anwendung. Ich hatte bereits mehrfach die Zweck-Beschreibung "Proxy" genannt. Schade, wenn so etwas direkt zur Assoziation "illegal" führt.

Für mich ist das Thema hier erledigt.
 
Zurück
Oben